3

In a Swift app, I am attempting to nest structures for greater clarity. Here is the code:

struct ColorStruct {
    var colorname: String = ""
    struct RGB {
        var red:   Int = 0
        var green: Int = 0
        var blue:  Int = 0
    }
}

I can access a ColorStruct element (example: "colorname") as long as it isn't nested.

Q: What am I failing to understanding about how to properly access the "red" variable?

var newColor = ColorStruct()
newColor.colorname = "Red"
newColor.RGB.red   = 255     // Results in error:
// Static member 'RGB' cannot be used on instance of type `ColorStruct`
Max Desiatov
  • 5,087
  • 3
  • 48
  • 56
Vic W.
  • 817
  • 1
  • 7
  • 9
  • `struct RGB { var red:Int = 0; var green:Int= 0; var blue:Int = 0; }; struct ColorStruct { var colorname:String = ""; var RGB:RGB;}` instead? ? – Larme Feb 22 '18 at 15:06
  • I've used separate structs as you show, but my point is that I am trying to nest structs for greater clarity. – Vic W. Feb 22 '18 at 15:08
  • The `ColorStruct` doesn't know about `struct RGB` without adding the `var RGB: RGB` to the `ColorStruct`. – MwcsMac Feb 22 '18 at 15:20
  • please note that `var RGB: RGB` wouldn't compile at all because of name collision between type name and variable name – Max Desiatov Feb 22 '18 at 15:21

5 Answers5

6

A nested struct as given in the question code doesn't automatically create an outer struct member of that type. To achieve that, refine the code this way:

struct ColorStruct {
  var colorname: String = ""
  struct RGB {
    var red:   Int = 0
    var green: Int = 0
    var blue:  Int = 0
  }

  var rgb = RGB()
}

var color = ColorStruct()
color.rgb.red = 255
Max Desiatov
  • 5,087
  • 3
  • 48
  • 56
  • 1
    Max, thank you. Your answer achieves both my goals: understanding why and clarity in code. – Vic W. Feb 22 '18 at 15:20
2

This line:

struct RGB{ var red: Int = 0}

states that red is an instance variable in a struct RGB (with other words, red does belong to an instance of RGB). When you create a struct of type ColorStruct, you do not create a struct RGB. You can only access instance variabele if you have created an object of it. If you want to access the variabele red, create a struct RGB (RGB()), or make the variabele/struct (is this possible in Swift?) static (don't make it an instance variabele).

J. Doe
  • 12,159
  • 9
  • 60
  • 114
1

You cannot assign value to struct just like that. Either create a new property of RGB like so,

struct ColorStruct {
  var colorname:String    = ""
  var rgb = RGB()

  struct RGB {
    var red:            Int    = 0
    var green:          Int    = 0
    var blue:           Int    = 0
  }

}

var newColor = ColorStruct()
newColor.colorname = "Red"
newColor.rgb.red   = 255     // Results in error:

Or, make static variable inside ColorStruct,

struct ColorStruct {
  var colorname:String    = ""
  static var rgb = RGB()

  struct RGB {
    var red:            Int    = 0
    var green:          Int    = 0
    var blue:           Int    = 0
  }
}

ColorStruct.rgb.red = 255
Sandeep
  • 20,908
  • 7
  • 66
  • 106
0

You can achieve it by this:

struct ColorStruct {
var colorname:String  = ""
var colorValue: RGB!

struct RGB              {
    var red:            Int    = 0
    var green:          Int    = 0
    var blue:           Int    = 0

    mutating func setRed(value: Int) {
        self.red = value
    }
    mutating func setGreen(value: Int) {
        self.green = value
    }
    mutating func setBlue(value: Int) {
        self.blue = value
    }
}
}

And then use the struct as:

var color = ColorStruct()

color.colorname = "blue"
color.colorValue = ColorStruct.RGB.init(red: 0, green: 0, blue: 1)
print(color.colorValue)

And if you want to change a value call this :

color.colorValue.setRed(value: 2)
print(color.colorValue)

Hope it helps

Agent Smith
  • 2,873
  • 17
  • 32
  • Thank you, but while it certainly works it (arguably) does not improve clarity. My goal is twofold: Better clarity in my code -and- understanding why my code does NOT work. – Vic W. Feb 22 '18 at 15:16
  • @VicW. you need to create an object(Passed by value) of the struct if you want to use and to modify any value inside it you will have to call mutating functions. – Agent Smith Feb 22 '18 at 15:19
  • @VicW. its explained beautifully [here](https://stackoverflow.com/questions/24232799/why-choose-struct-over-class/24232845#24232845) – Agent Smith Feb 22 '18 at 15:20
0

You must instantiate your RGB struct instead of ColorStruct:

struct ColorStruct {
    var colorname:String    = ""
    struct RGB              {
        var red:            Int    = 0
        var green:          Int    = 0
        var blue:           Int    = 0
    }
}

var newColor = ColorStruct.RGB()
newColor.red = 255
sebastien FCT
  • 630
  • 1
  • 13
  • 28
  • Sebastien, thank you. My problem with this approach is that when the enclosing ColorStruct has multiple nested structs, the instantiation becomes increasingly complex as additional nested structs are added. – Vic W. Feb 22 '18 at 15:25