1
class C{
 var b:[String]?
 subscript(i:Int)->String?{
  get{
   return b?[i]
  }
  set{
   b?[i] = newValue! // notice the unwrapped “!” here
  }
 }
}

In the code, I put a exclamation mark "!" to unwrap the newValue, Because newValue is the same type of the return value of subscript which is String?. If I don't put the exclamation mark "!" it will report error: "

error: cannot assign value of type 'String?' to type 'String' b?[i] = newValue

" Question: b?[i] is obviously an optional String value String?, how come it is of type String. I wonder it was a bad error code

3 Answers 3

2

Your var b: [String]? is an optional array. However the string inside is not optional. If you changed it to: var b: [String?]? then it would work.

Sign up to request clarification or add additional context in comments.

Comments

1

You property b is indeed an optional array, but its member elements are not optionals. Hence, when attempting to assign a new value to an existing member, the new value must be of concrete type String, and not the optional type String?.

// this is an Optional array, with non-optional elements
var foo: [String]? = ["foo"]

let optStr: String? = "bar"
let nonOptStr = "bar"

// ok, nonOptStr is not an optional
foo?[0] = nonOptStr

// as for 'nonOptStr', we need to unwrap
// it prior to attempting to assign it as a 
// replacement member of 'foo'
if let str = optStr {
    foo?[0] = str
}

Also, avoid explicit unwrapping, and consider validating the index prior to using it. E.g.:

class C {
    var b: [String]?
    subscript(i: Int) -> String? {
        get {
            if b?.indices.contains(i) ?? false { return b?[i] }
            return nil            
        }
        set {
            if b?.indices.contains(i) ?? false, let newValue = newValue {
                b?[i] = newValue
            }
        }
    }
}

Comments

0

More generally, I found myself with this exact error after doing a split on a string and ended up printing out both variables. That clarified that I was trying to assign a two element variable to an indexed array that contained a string. So, that is the source of the error, which is essentially saying your trying to assign two elements of an array into a string inside your other array. Well, that makes sense out of the error.
Algorithmically it is: 1) array1[0] = array2Item1, array2Item2

That's why this was fine: 2) array1 = array2Item1, array2Item2

but the above was not.

So, the correct thing to do is 2) and then assign it by index:

array1 = array2Item1, array2Item2

array3 = array1[0] to do what I thought I was doing in 1).

Just another explanation for any others who venture here.

Comments

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.