2016-08-19 2 views
28

довольно простой кусок кода«Невозможно присвоить значение типа„String“к типу 'AnyObject?», Swift 3, Xcode 8 бета 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? Или это ошибка?

ответ

32

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

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

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

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

(Убедитесь, что по ссылке Хэмиш обеспечивает в комментариях ниже.)

+0

Спасибо за ответ, все было так же, как я подозревал. Эта ложноположительная проверка типа - единственная причина, по которой я задал этот вопрос. – xinatanil

+2

[Согласно Джо Гроффу (https://bugs.swift.org/browse/SR-2420?focusedCommentId=17394&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-17394), ' is/as AnyObject' всегда должен преуспеть, так как теперь все мосты «AnyObject». Я считаю, что это связано с тем, что 'id' теперь подключен к Swift как' Any', 'Any' теперь может быть подключен к' AnyObject' (странно, я знаю). – Hamish

+1

И да, похоже, что swift испытывает проблемы с проверкой типа AnyObject http://stackoverflow.com/questions/39033194/anyobject-not-working-in-xcode8-beta6 – xinatanil

4

Я дополнение к @RobNapier's answer с некоторыми официальными источниками.


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

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

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

... [Из SE-0072]

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

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

...

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

...

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

Наконец, the release notes for Xcode 8 beta 6 (Войти требуется) заявляет, что это предложение в настоящее время реализована для бета 6:

Новое в Xcode 8 бета-6 - Swift Составитель: Swift Язык

...

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

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

Смежные вопросы