2

I'm trying to create a sparse array in Swift. I'm not sure if the problem is in my declaration (no syntax errors detected) or possibly a bug in beta 2?

I am trying to declare an array of 24 class instances as optionals. I then can fill in slots of the array as necessary. Here is the declaration:

var usage = WaterUsage?[](count:24, repeatedValue:nil)

This gets through the Xcode 6 beta 2 compiler without error. The intention is to end up with an array of 24 "WaterUsage" classes all set to nil.

When I try to set an array element:

usage[hour] = usage

where hour is < 24 I get the error:

"WaterUsage doesn't have a member named subscript"

I've also tried using generics but that doesn't appear to work either.

I find the Swift syntax for using optionals in complex data structures is a little obscure and could use some advice here.

1
  • your code doesn't actually read usage[hour] = usage, does it? if so I could see that being a problem Commented Jul 3, 2014 at 17:14

2 Answers 2

4

That way of defining the array is giving you an Optional array of Optional values ( WaterUsage?[]? ), which you have to unwrap before you can use. I think you want just the values to be optional: WaterUsage?[]. One way I've been able to do that is by using the generic Array syntax:

var usage: WaterUsage?[] = Array<WaterUsage?>(count:24, repeatedValue:nil)
usage[hour] = something

Another way is to force unwrapping of the return value of your initial declaration. I don't know why, but WaterUsage?[]() has an Optional return value.

var usage = (WaterUsage?[](count:24, repeatedValue:nil))!
usage[hour] = something
Sign up to request clarification or add additional context in comments.

5 Comments

Tried both and got the same error. Also tried unwrapping usage before the subscript and also got the same error
<code>import Foundation class DayUsage { var usage = WaterUsage?[](count:24, repeatedValue:nil) func addInterval(hour:Int, usage:WaterUsage?) { if (hour >= 0 && hour < 24) { usage![hour] = usage } } }</code>
I think the parameter usage is overriding the instance variable usage. Rename the parameter?
The combination of changing the parameter name (I should have known better...) and using parentheses around the WaterUsage? declaration seemed to have solved it
Great! I wish Swift required self for property access. Wouldn't have let you get into trouble.
0

You're pretty close! When using the MemberType[] syntactic sugar for arrays, the way that you wrote it (WaterUsage?[]) actually declares the Array as Optional, as well as the values that it holds. In which case, to assign a value to an index you would need to unwrap the Array first by using:

usage![hour] = someWaterUsage

However, if you only want Optional members in the Array (and don't want the Array itself to be optional), then you can fall back to the standard Array declaration:

var usage = Array<WaterUsage?>(count:24, repeatedValue:nil)

edit:

I originally offered an alternate syntax as another solution as well:

var usage = (WaterUsage?)[](count:24, repeatedValue:nil)

...but in doing so, per @Nate's observations it then becomes the case that you need to use unwrapping twice to access the value at a specific index, for example:

usage[0]!!.someProperty

this is just a shot in the dark, but I think what may be happening in this case is not dissimilar at all to what OP originally tried with declaring the Array using WaterUsage?[]

that is, when using (WaterUsage?)[], perhaps it is seeing this declaration as an Array of Optional Tuples holding Optional WaterUsages, requiring us then to unwrap the member at the index twice before we can access its properties

interesting stuff!

5 Comments

There's definitely some Swift bugginess around declaring arrays of Optionals. With your first declaration the resulting type is WaterUsage??[], which means you have to unwrap array members twice before you can access them: usage[0]!!.someProperty.
dude! that is crazy :)
actually I just checked, and that is not the case for me at all - if I substitute String for WaterUsage I don't need to unwrap it at all to access it
oh weird, I see it now, tried it with an object - strangeness!
tried everything here (generics, parenthesis, unwrapping) and still got the subscript error

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.