Подтвердить что ты не робот

"Невозможно присвоить значение типа" String "для ввода" AnyObject? ", Swift 3, Xcode 8 beta 6

Довольно простой фрагмент кода

var dict: [String: AnyObject] = [:]
dict["key"] = "value"

генерирует следующую ошибку времени компиляции

Cannot assign value of type 'String' to type 'AnyObject?'

Простые проверки типов говорят мне, что String есть AnyObject

"value" is AnyObject // returns true

Я мог бы изменить AnyObject на Any, и все будет работать

var dict: [String: Any] = [:]
dict["key"] = "value"

но я хочу понять, почему я получаю ошибку? Является String больше AnyObject? Или это ошибка?

4b9b3361

Ответ 1

В b6 строка больше не магически соединяется с NSString. Строка не является классом; это структура. Вам нужно сделать мост вручную:

dict["key"] = "value" as AnyObject

Тот факт, что is все еще кажется мостом, вероятно, является ошибкой и должен быть сообщен.

Само собой разумеется, что [String: AnyObject] и [String: Any] должны использоваться как можно меньше в вашем коде.

(Обязательно следуйте ссылке, приведенной в комментариях ниже).

Ответ 2

Я добавлю к ответу @RobNapier с некоторыми официальными источниками.


Удаление механизмов неявного моста было принято в следующем предложении по эволюции Swift, которое должно быть реализовано для Swift 3

Ранее неявные преобразования были доступны из некоторых родных типов Swift до, связанных Objective-C (типы Swift, соответствующие частному протоколу _ObjectiveCBridgeable, например, изначально Int, String,)

По этой причине мы решили пойти на компромисс. Мы бы требовали явные перетаскивания при трансляции при преобразовании из мостового Objective-Cвведите в связанный с ним тип значения Swift (например, NSString → String), , но не наоборот.

... [С SE-0072]

С Swift 3 такие механизмы неявного преобразования больше не будут доступны.

С введением в прошлом году дженериков Objective-C, наряду с все удивительные улучшения в импорте API для Swift 3, я думаю, что время, когда мы еще раз посмотрим на завершение этого работа.

...

Я предлагаю, чтобы мы полностью исключали неявные переходы моста в Swift 3. Это означает, что некоторые пользователи могут более явные приведения в свой код, но мы удалили бы еще одну специальную случае из системы типа Swift и иметь возможность дополнительно упростить компилятор.

...

Код, который ранее полагался на неявные преобразования между Swift типы значений и связанный с ними мостовой тип Objective-C требуется ручное принуждение с помощью as cast.

Наконец, в примечаниях к выпуску для Xcode 8 beta 6 (требуется логин) говорится, что это предложение теперь реализовано для бета-версии 6:

Новое в Xcode 8 beta 6 - Swift-компилятор: Swift Language

...

  • Преодоление конверсий больше не подразумевается. Преобразование из типа значения Swift в соответствующий объект может быть принудительно с помощью as. Например: string as NSString. Любое значение Swift также может быть преобразуется в его представление в ящик с идентификатором as AnyObject. (SE-0072)

W.r.t. новый "boxed id", позволяющий явное преобразование для любого значения Swift до AnyObject, см., например, следующий поток: