Swift: Cannot convert value of type 'Int?' to specified type 'UInt32' - swift

I'm trying to assign an array count to a UInt32. I get the error "Cannot convert value of type 'Int?' to specified type 'UInt32'". The array count is type Int, but the error says "Int?", which looks like an optional Int. I have no idea what else it could mean.
let randColorCount:UInt32 = slider?.randUIColors.count
I've also tried:
let randColorCount:UInt32 = UInt32(slider?.randUIColors.count)
But I get the error "Cannot invoke initializer for type 'UInt32' with an argument list of type '(Int?)'".

slider?.randUIColors.count results in Int? because of the use of the optional chaining.
One simple solution is to combine this with the nil coalescing operator ?? to provide a default value incase slider is nil.
let randColorCount = UInt32(slider?.randUIColors.count ?? 0)

Related

In Swift, how do I explicitly specify a return value for map with anonymous closure arguments?

Say I call map like this, using the anonymous closure argument $0:
array.map {
return $0.description
}
How would I explicitly define that map returns a string? This doesn’t work:
array.map { -> String
return $0.description
}
Contextual type for closure argument list expects 1 argument, which cannot be implicitly ignored
Does that mean if I want to specify a return value I have to name my arguments?
[EDIT: I know I do not need an explicit return type here; still would like how to specify one]
You can use as to identify the type of the anonymous enclosure. In this case you'll need to specify the type of the input as well:
let result = array.map({ $0.description } as (CustomStringConvertible) -> String)
Note: You could use the type of whatever is in array as the input type. Here I just used the CustomStringConvertible protocol since that is what is needed to be able to access the .description property.
or as you mentioned, you can specify the output type if you give a name to the input parameter:
let result = array.map { value -> String in value.description }
Another way to look at it is to note that map returns an Array of whatever type the map closure returns. You could specify that the result of the map is [String] and Swift would then infer that the map closure returns String:
let result = array.map({ $0.description }) as [String]
or
let result: [String] = array.map { $0.description }
The type will be inferred automatically if it's a string , otherwise you need a cast like this
array.map { String($0.description) }

What's the Purpose of "an Optional of an Optional" in Swift Optional Types?

I found an interesting function in the Swift Tests source code:
func test(_ v: A????, _ cast: (A????) -> B?)
Since Type? is just syntax sugar for Optional<Type>, this means that the type of the argument v can be rewritten as Optional<Optional<Optional<Optional<A>>>>.
I know that this function is used to test optional types, so it is definitely going overboard with the arguments v and cast, but what would be the actual use of having "an optional of an an optional, etc." type in Swift (if any)?
These occur sometimes in Swift when you are accessing data.
One example is if you have a dictionary with an optional type for the value, and then you look up a value in that dictionary:
let rockStars: [String: String?] = ["Sting": nil, "Elvis": "Presley", "Bono": nil, "Madonna": nil]
let lastName = rockStars["Elvis"]
print(lastName as Any)
Optional(Optional("Presley"))
This happens because a dictionary look up can fail when the key is not present, and it returns nil in that case. So the return type of a dictionary lookup has to be the value type wrapped in an optional. A look up from the rockStars dictionary returns a String??.

What is the meaning of "??" in swift? [duplicate]

This question already has answers here:
?? operator in Swift
(5 answers)
Closed 5 years ago.
I came across a syntax in Swift where double question marks are used ("??").
For instance, let val = something["something"] as? String ?? nil
What exactly does this mean? What are some use cases for this syntax?
Nil-Coalescing Operator
It's kind of a short form of this. (Means you can assign default value nil or any other value if something["something"] is nil or optional)
let val = (something["something"] as? String) != nil ? (something["something"] as! String) : "default value"
The nil-coalescing operator (a ?? b) unwraps an optional a if it contains a value, or returns a default value b if a is nil. The expression a is always of an optional type. The expression b must match the type that is stored inside a.
The nil-coalescing operator is shorthand for the code below:
a != nil ? a! : b
The code above uses the ternary conditional operator and forced unwrapping (a!) to access the value wrapped inside a when a is not nil, and to return b otherwise. The nil-coalescing operator provides a more elegant way to encapsulate this conditional checking and unwrapping in a concise and readable form.
If the value of a is non-nil, the value of b is not evaluated. This is known as short-circuit evaluation.
The example below uses the nil-coalescing operator to choose between a default color name and an optional user-defined color name:
let defaultColorName = "red"
var userDefinedColorName: String? // defaults to nil
var colorNameToUse = userDefinedColorName ?? defaultColorName
// userDefinedColorName is nil, so colorNameToUse is set to the default of "red"
See section Nil-Coalescing Operator here
This operator is generally used to provide a default value when an expression or variable produces an optional result. for ex:
let i: Int? = 5
let j: Int? = nil
let value1 = i ?? 9 //value1 will be 5 non-optional
let value2 = j ?? 9 //value2 will be 9 non-optional
You can chain multiple of these operators as such:
let value3 = j ?? i ?? 9 //value3 will be 5 non-optional
The chain terminates whenever a non nil value is found. The result of the expression will be a optional/non-optional depending on the type of last expression in the chain.
The example you've provided, although syntactically correct, is redundant, as omitting the ?? nil would have no result on the outcome.
This is Nil-Coalescing Operator in Swift.
Nil-Coalescing Operator
The nil-coalescing operator (a ?? b) unwraps an optional a if it
contains a value, or returns a default value b if a is nil. The
expression a is always of an optional type. The expression b must
match the type that is stored inside a.
But in your example you already using optional binding , so no need of using ?? with optional, if it fails condition then it automatically assign nil.
let val = something["something"] as? String ?? nil
Here, something["something"] as? String, already assign nil, if something["something"] fails to deliver String. So no need of this operator here.

Cannot use mutating member on immutable value of type [String]

I failed to append String by using following code:
(labGroups[labGroupIndex!].labs[labIndex!].tstDspGps[tstDspGpsIndex!].tests[testsIndex!]["specialReqValues"] as![String]).append("sdfsdf")
Error:
Cannot use mutating member on immutable value of type
'[String]'
And I can append value by using following code:
var arr = labGroups[labGroupIndex!].labs[labIndex!].tstDspGps[tstDspGpsIndex!].tests[testsIndex!]["specialReqValues"] as![String]
arr.append("testValue")
However, it only affect the variable arr.
That is not what I want, when I print:
((labGroups[labGroupIndex!].labs[labIndex!].tstDspGps[tstDspGpsIndex!].tests[testsIndex!]["specialReqValues"] as![String]))
it still has nil value.
Can anyone help to solve this problem?

why there need add '!' in code suffix

enum Season: Int {
case Spring = 0
case Summer = 1
case Autumn = 2
case Winter = 3
}
var SeasonTime1 = Season.Spring
//why ? this code suffix need add !
SeasonTime1 = Season.init(rawValue: 2)!
List item
// why? there don't need add !
var SeasonTime2 = Season.init(rawValue: 2)
This is because Enum uses a failable initializer (see documentation here). As its title implies, a failable initilizer can fail and return nil. Objects that can contain nil are Optionals in Swift. Therefore you could have:
let seasonTime1 = Season.init(rawValue: 2)
In which case the type of seasonTime1 is Optional<Season>. When you want to use the value, you then have to unwrap the Optional, either using if let, guard or !. In this case:
let seasonTime1 = Season.init(rawValue: 2)!
You're unwrapping it immediately, so the type of seasonTime1 will be Season. Note the following code:
let seasonTime1 = Season.init(rawValue: 2222)!
This will run, but if you access seasonTime1 it will fail. This is because there is no enum with a raw value of 2222, and so seasonTime1 will contain nil. Since it is implicitly unwrapped, the fact that it contains nil is illegal, which will cause a crash if the unwrapping occurs.
Because the compiler cannot infer that the raw value type exists so you need the '!' too force unwrap it. If you wrap it in a guard statement you can ensure that it is of the type that "you" know it is. Then you don't need the '!'