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

}
Другие вопросы по тегам