Reputation: 621
How to declare [Int] in optional
I try
var listofNumber = [Int]?()
But it's not working
But if I try
var listofNumber : [Int]?
The problem is I cant use listofNumber.append anymore
Value of type '[Int]?' has no member 'append'
Upvotes: 0
Views: 804
Reputation: 3261
You are writing [Int]?
but this is just syntactic sugar.
Behind the scenes, what you're actually declaring isOptional<[Int]>
.
If you look at the documentation for Optional<T>
, you can see that there are three initialisers declared for this value type:
init(from: Decoder) throws
This one is used in conjunction with the coding protocols introduced in Swift 4. It is of no relevance here.init(nilLiteral: ())
This one initialises the Optional<T>
to nil
.init(some: T)
This one initialises the Optional<T>
to T
.Your statement var listOfNumbers = [Int]?()
does not match any of the initialisers and thus is not working.
Now what you probably want to do - and what most of us would presumably do here - is:
var listOfNumbers: [Int]? = []
This declares the type of listOfNumbers
to be [Int]?
(aka Optional<[Int]>
) and at the same time sets its initial value to an empty array.
The crucial thing to note here is that virtually all of this is syntactic sugar. If you went out of your way and defined the var "natively", it would look something like this:
var listOfNumbers = Optional<[Int]>(Array<Int>())
.
(You could leave out the generic parameter to Array
, as it would be inferred by the type system here.)
Since this is cumbersome to write and also doesn't read quite well, you can use the short version.
As for the second issue regarding Array.append
.
Your var is of type [Int]?
(aka Optional<[Int]>
) and thus you cannot access vars or call methods defined on the Array
type. You need to unwrap the optional first.
listOfNumbers?.append(4711)
.
If you're using Xcode, it should actually provide you with a fix-it for this kind of issue.
Now since we were talking about "explicitness" anyway:
listOfNumbers?.append(4711)
is again a shiny example for syntactic sugar.
Explicitly written, it would look something like this:
// Optional<T> is actually an enum, so we can switch over it.
switch listOfNumbers {
case .some(var value):
value.append(4711)
case .none:
break
}
// Alternative
if case .some(var value) = listOfNumbers {
value.append(4711)
}
As you can see, this is quickly getting bloated, especially considering optional chaining, etc. Hence, the short version was "invented".
I've written this long answer to make it clear to you what's going on behind the scenes here and I guess it never hurts to remind yourself of the nuts and bolts you’re building upon sometimes.
Note that it would be perfectly valid for you to write the statement like this:
var listOfNumbers = [Int]?([])
or
var listOfNumbers = [Int]?(nilLiteral: ())
The amount of syntactic sugar you are using it up to you and you can mix it with "explicit" coding however you want.
Upvotes: 5
Reputation: 58103
For declaring use this syntax:
var listOfNumber: [Int]? = []
Then use any method you need:
listOfNumber?.append(20)
listOfNumber?.insert(40, atIndex: 1)
listOfNumber! // result: [20,40]
Second part.
Here's your code:
if listOfNumber?[0] == nil {
print("if access...")
} else {
listOfNumber?.append(20)
print(listOfNumber!)
}
Upvotes: 2
Reputation: 5588
var listofNumber : [Int]?
is the good approch.
Dont forget to init
using
var listofNumber : [Int]? = []
or var listofNumber : [Int]? = nil
After, as the array is optional, use listofNumber?.append(10)
.
Upvotes: 1