Swift 1.2 объединенная строка
Я получаю ошибки при конкатенации строки:
let likeKey = "like-" + foodPhotoObjects[indexPath.row].objectId
ошибка
binary operator '+' cannot be applied to operands of type 'String' and 'String?!'
2 ответа
Итак, у вас есть неявно завернутый необязательный элемент необязательной строки, что-то вроде этого:
struct Thing {
let objectId: String?!
}
let foodPhotoObjects: [Thing] = [Thing(objectId: "2")]
С любым дважды обернутым необязательным, чтобы добраться до объекта внутри, вам нужно будет развернуть его дважды:
// first unwrap the String?! into a String?
if let outer = foodPhotoObjects[0].objectId,
// then unwrap that String? into a String
inner = outer {
// inner is now a String
println("like-\(inner)")
}
Ключ здесь, хотя внешний необязательный неявный (то есть !
скорее, чем ?
), вы все еще можете развернуть неявные опционные функции, используя if let
Таким образом, неявность не имеет значения при этом.
Альтернативный способ обработки такого рода вещей, а не if-let, заключается в использовании map
:
let concatedString = foodPhotoObjects[indexPath.row].objectId.map {
"like-" + $0
} ?? ""
map
по необязательному средству: если необязательный содержит значение, измените значение с помощью этой функции и верните его как необязательное, в противном случае верните nil
, Итак, разверните String?
и добавьте "как" к нему.
??
на факультативное средство: если предыдущее значение nil
замените его на значение по умолчанию в правой части (пустая строка), в противном случае разверните его и верните его (то есть значение, которое мы только что отобразили).
Теперь о хитрой части: потому что значение мы называем map
on является неявным необязательным, он будет неявно развернут, то есть map
вызывается на внутренней String?
а не на String?!
, Это не похоже на случай с if let
где это было выполнено сначала по неявному необязательному, затем по внутреннему необязательному.
Как и со всеми неявными опциями, существует риск того, что они могут быть nil
в этом случае ваш код взорвется, вот так:
let explode = Thing(objectId: nil)
// the next line will generate fatal error: unexpectedly
// found nil while unwrapping an Optional value
explode.objectId.map { "like-" + $0 }
Если это проблема, вы можете избежать этого с помощью некоторой необязательной цепочки:
// note, ? after objectId
let concatedString = foodPhotoObjects[indexPath.row].objectId?.map {
"like-" + $0
} ?? ""
Этот фрагмент может выиграть приз за большинство необязательных методов обработки, объединенных в одно утверждение... но он должен делать то, что вам нужно.
Swift не выполняет неявное преобразование, даже если оба имеют одинаковый тип, а один из них необязательного типа.
Попробуй это.
var concatedString = ""
if let foodphoto = foodPhotoObjects[indexPath.row].objectId as? String {
concatedString = "like-" + foodphoto
}