Ответ 1
Когда вы говорите:
Мое понимание необязательной цепочки состоит в том, что после того, как вы начнете использовать
?.
в точечном выражении, остальные свойства становятся необязательными и к ним обычно обращаются?.
, а не.
.
Я бы сказал, что вы почти там.
Не то, чтобы все свойства были сделаны необязательными, так что исходный вызов является необязательным, поэтому он выглядит так, как другие свойства являются необязательными.
characters
не является необязательным свойством и не является count
, но значение, которое вы вызываете, является необязательным. Если есть значение, то свойства characters
и count
возвращают значение; в противном случае возвращается nil
. Именно из-за этого результат s?.characters.count
возвращает Int?
.
Если какое-либо из свойств было необязательным, вам нужно добавить к нему ?
, но в вашем случае они не являются. Так ты не делаешь.
Отредактировано следующим комментарием
Из комментария:
Мне все еще кажется странным, что оба
s?.characters.count
и(s?.characters)?.count
скомпилированы, но(s?.characters).count
этого не делает. Почему существует разница между первым и последним выражением?
Попытайтесь ответить на него здесь, где больше места, чем в поле комментария:
s?.characters.count
Если s
равно nil, все выражение возвращает nil
, в противном случае Int
. Таким образом, тип возврата Int?
.
(s?.characters).count // Won’t compile
Прервать это: если s
- nil
, то (s?.characters)
- nil
, поэтому мы не можем называть его count
.
Чтобы вызвать свойство count
на (s?.characters)
, выражение нужно по желанию распаковать, то есть записать как:
(s?.characters)?.count
Отредактировано для добавления дополнительных
Лучшее, что я могу объяснить, это этот бит кода площадки:
let s: String? = "hello"
s?.characters.count
(s?.characters)?.count
(s)?.characters.count
((s)?.characters)?.count
// s?.characters.count
func method1(s: String?) -> Int? {
guard let s = s else { return nil }
return s.characters.count
}
// (s?.characters).count
func method2(s: String?) -> Int? {
guard let c = s?.characters else { return nil }
return c.count
}
method1(s)
method2(s)