Ответ 1
Другое решение, которое работает в Swift 3, - это отбросить Decimal
до NSNumber
и создать Double
.
let someDouble = Double(someDecimal as NSNumber)
Я перевожу проект из Swift 2.2 в Swift 3 и пытаюсь по возможности избавиться от старых типов данных Cocoa.
Моя проблема здесь: миграция NSDecimalNumber
в Decimal
.
Я использовал, чтобы соединить NSDecimalNumber
к Double
оба способа Swift 2.2:
let double = 3.14
let decimalNumber = NSDecimalNumber(value: double)
let doubleFromDecimal = decimalNumber.doubleValue
Теперь переключаемся на Swift 3:
let double = 3.14
let decimal = Decimal(double)
let doubleFromDecimal = ???
decimal.doubleValue
не существует, ни Double(decimal)
, даже не decimal as Double
... Единственный хак, который я придумал, это:
let doubleFromDecimal = (decimal as NSDecimalNumber).doubleValue
Но было бы совершенно глупо пытаться избавиться от NSDecimalNumber
и использовать его время от времени...
Ну, или я пропустил что-то очевидное, и прошу прощения за трату вашего времени, или, на мой взгляд, нужно было устранить лазейку...
Заранее спасибо за помощь.
Изменить: больше ничего на эту тему на Swift 4.
Изменить: ничего больше на эту тему на Swift 5.
Другое решение, которое работает в Swift 3, - это отбросить Decimal
до NSNumber
и создать Double
.
let someDouble = Double(someDecimal as NSNumber)
NSDecimalNumber
и Decimal
соединены
Наложение Swift на платформу Foundation предоставляет структуру Decimal, которая соединяется с классом NSDecimalNumber. Тип десятичного значения предлагает те же функциональные возможности, что и ссылочный тип NSDecimalNumber, и они могут использоваться взаимозаменяемо в коде Swift, который взаимодействует с API-интерфейсами Objective-C. Это поведение аналогично тому, как Swift соединяет стандартные строковые, числовые типы и типы коллекций с соответствующими им базовыми классами. Apple Docs
но, как и с некоторыми другими мостовыми типами, некоторые элементы отсутствуют.
Чтобы восстановить функциональность, вы можете написать расширение:
extension Decimal {
var doubleValue:Double {
return NSDecimalNumber(decimal:self).doubleValue
}
}
// implementation
let d = Decimal(floatLiteral: 10.65)
d.doubleValue
Decimal
в Swift 3 не NSDecimalNumber
. Это NSDecimal
, совершенно другой тип.
Вы должны просто использовать NSDecimalNumber
, как и раньше.
Решение, которое работает в Swift 4
let double = 3.14
let decimal = Decimal(double)
let doubleFromDecimal = NSDecimalNumber(decimal: decimal).doubleValue
print(doubleFromDecimal)
Изменить: без NSDecimalNumber
/NSNumber
let double = 3.14
let decimal = Decimal(double)
if let doubleFromDecimal = Double(decimal.description){
print(doubleFromDecimal)
}
Вы должны использовать в as
оператора для приведения типа Swift к его мостовому базовому типу Objective-C. Так что просто используйте as
это.
let p = Decimal(1)
let q = (p as NSDecimalNumber).doubleValue
В Swift 4 Decimal
является NSDecimalNumber
. Вот цитата из официальной документации Apple в Xcode 10.
Важный
Наложение Swift на платформу Foundation предоставляет структуру
Decimal
, которая соединяется с классомNSDecimalNumber
. Для получения дополнительной информации о типах значений см. Работа с фреймворками Cocoa в Использовании Swift с Cocoa и Objective-C (Swift 4.1).
Там нет NSDecimal
больше. В Swift 3 был запутанный тип NSDecimal
, но, похоже, это ошибка. Нет больше путаницы.
Я вижу, что OP не заинтересован в Swift 4, но я добавил этот ответ, потому что упоминание только о (устаревшем) Swift 3 привело меня в замешательство.
let doubleValue = Double(truncating: decimalValue as NSNumber)