2016-10-24 2 views
2

В проекте «Тесты» у меня есть расширения с некоторыми тестовыми вспомогательными функциями. Например:Не удалось отличить значение типа «Swift.UInt32» с «Swift.Int»

extension Employee { 
    static func mockDict() -> Dictionary<String, Any>! { 
     return ["ID": arc4random() % 1000, 
       "FirstName": "Employee First Name", 
       ...] 
    } 
} 

(Я снял ненужный код). У меня есть проблема доступа к ID из этого словаря по какой-то еще неизвестной причине. У меня SIGABRT 6 при литье

employeeDict["ID"] as! Int 

Xcode отладчик консоли также не нравится это конкретное целое:

Ints

Строки работает отлично. Вы столкнулись с такой проблемой? Есть идеи?

EDIT: На всякий случай кто-то столкнется с этой проблемой. КАСТИНГ ОТ UInt32/Int32 TO Int FAILS BY DESIGN. Даже если объект был отлит в Any или Anyobject между ними. Даже если

@available(*, message: "Converting UInt32 to Int will always succeed.") 
public init?(exactly value: UInt32) 

в декларации Int в

public struct Int : SignedInteger, Comparable, Equatable { 
    ... 
} 

и

public struct Int32 : SignedInteger, Comparable, Equatable { 
    ... 
} 

EDIT 2 для тех, кто может столкнуться такое поведение в JSON сериализации. Да, сериализация с ошибкой NSInvalidArgumentExceptionInvalid type in JSON write (_SwiftValue), если просят сериализации UInt32, Int64 или любой экземпляр протокола Integer, кроме Int

ответ

5

Попробуйте это:

let a = employeeDict["ID"] as! UInt32 
let number = Int(a) 

Теперь вы можете использовать number для выполнения каких-либо действий.

+0

Спасибо, я сделал обходной путь таким образом. Но я все еще сбиваюсь с толку, потому что приложение работает на iPhone 7 sim, где Int - 64 бит. Также 892 определенно является Integer, который не будет вызывать переполнение или любые другие проблемы. – user1232690

+0

Я думаю, проблема в том, что вы пытаетесь указать число как целое, а не целое число из UInt32. Кроме того, если бы мой ответ помог вам, не могли бы вы принять его? Благодаря! – penatheboss

+1

Готово. Я добавил некоторые детали в вопрос. BTW, только универсальный способ, который я нашел, - использовать 'NSNumber', чтобы добавить возможность использовать экземпляры протокола Integer в' Int' без сбоев. – user1232690

1

Быстрые «примитивные» числовые типы не являются взаимозаменяемыми и не могут быть отброшены друг к другу.

Вам необходимо использовать инициализатор.

С arcRandom() возвращается UInt32 и вы хотите использовать значение в качестве Int, конвертировать его сразу в словаре декларации:

["ID": Int(arc4random() % 1000), ... 

PS: Не объявить явно не опциональным, как неявные развернутый по желанию возвращающее значение, которое побеждает сильную систему Swift.

static func mockDict() -> Dictionary<String, Any> 
+0

Сначала я столкнулся с этой проблемой в JSONSerialization. После углубления я обнаружил проблему, которую я перечислил в вопросе.Нет простого решения для литья целых чисел, отличных от Int, в Int, если они были занесены в Any First. Скажем, например, у нас есть адаптер Swift DB с целыми полями разного размера. В Objective C они могут быть переведены в объекты, а затем в целые числа или сериализованные. Поэтому я был озадачен отсутствием этой функции в Swift. – user1232690

+0

Относительно "!" возможно, что тестовая логика имеет нулевой результат, я просто удалил код для генерации возможных dicts. Таким образом, вы правы на этом, но все в порядке в реальном коде. – user1232690

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