2017-06-07 29 views
11

W Swift3, ja wcześniej przekształcone bool do int stosując następującą metodę„«init»jest przestarzała” ostrzeżenie po Swift4 konwertować

let _ = Int(NSNumber(value: false)) 

Po konwersji do Swift4, jestem coraz „«init» jest przestarzałe "ostrzeżenie. Jak inaczej powinno to być zrobione?

+7

To kod bardzo nierealne. Dlaczego nie "let _ = false"? 1: 0' – vadian

+0

Masz rację, to ma dużo więcej sensu, użyję tego. Dzięki! –

+0

@Vadian - Jestem n00b. Nie rozumiem, po co zawracać sobie głowę trójpoziomowym operatorem, jeśli masz zamiar nakarmić go "fałszywie". Dlaczego nie po prostu "let _ = 0"? –

Odpowiedz

14

z Swift 4, w zależności od potrzeb, można wybrać jedną z następujących czynności Pla fragmenty yground w celu rozwiązania Twojego problemu.


# 1. Korzystanie NSNumber „s intValue nieruchomość

import Foundation 

let integer = NSNumber(value: false).intValue 
print(integer) // prints 0 

# 2. Korzystanie typu odlew

import Foundation 

let integer = NSNumber(value: false) as? Int 
print(String(describing: integer)) // prints Optional(0) 

# 3. Korzystanie Int „s init(exactly:) inicjator

init(exactly:) ma następującą deklarację:

init?(exactly number: NSNumber) 

Zastosowanie:

import Foundation 

let integer = Int(exactly: NSNumber(value: false)) 
print(String(describing: integer)) // prints Optional(0) 

Jako alternatywę do poprzedniego kodu, można użyć poniższy kod bardziej zwięzłe .

import Foundation 

let integer = Int(exactly: false) 
print(String(describing: integer)) // prints Optional(0) 

# 4. Korzystanie z przepływu sterowania

Należy pamiętać, że poniższe kody nie wymagają importowania Foundation.

Wykorzystanie # 1 (if):

let integer: Int 
let bool = false 

if bool { 
    integer = 1 
} else { 
    integer = 0 
} 
print(integer) // prints 0 

Wykorzystanie # 2 (operator trójargumentowy):

let integer = false ? 1 : 0 
print(integer) // prints 0 
4

Można użyć NSNumber nieruchomości intValue:

let x = NSNumber(value: false).intValue 

Można również użyć init?(exactly number: NSNumber) inicjator:

let y = Int(exactly: NSNumber(value: false)) 

lub jak wspomniano w komentarzach przez @Hamish inicjatora numeryczna została zmieniona na init(truncating:)

let z = Int(truncating: NSNumber(value: false)) 

lub niech Xcode niejawnie cre zjadł NSNumber z niego jak wspomniano przez @MartinR

let z = Int(truncating: false) 

Inną opcją masz jest rozszerzenie protokołu BinaryInteger (SWIFT 4) lub Integer (Swift3) i tworzyć własne non omylny inicjator że trwa Bool jako parametr i zwraca oryginalny typ za pomocą operatora potrójny jak zasugerowano w komentarzach przez @vadian:

extension BinaryInteger { 
    init(_ bool: Bool) { 
     self = bool ? 1 : 0 
    } 
} 

let a = Int(true) // 1 
let b = Int(false) // 0 

let c = UInt8(true) // 1 
let d = UInt8(false) // 0 
+0

Świetnie, działa! Czy istnieje powód, dla którego poprzednia metoda jest przestarzała? –

+0

W Swift 4 nawet 'let x = Int (dokładnie: false)!' Działa – vadian

+5

Inicjatory 'init (_ :)' służące do konwersji z 'NSNumber' na Swift numeric zostały zmienione na' init (truncating:) 'as [SE-0170] (https://github.com/apple/swift-evolution/blob/master/proposals/0170-nsnumber_bridge.md) - czyli 'Int (obcięcie: NSNumber (value: false))'. Ale '.intValue' powinno osiągnąć ten sam wynik w tym przypadku (chociaż oczywiście jako vadian wskazuje, nie ma potrzeby, aby w pierwszej kolejności używać' NSNumber'). – Hamish

Powiązane problemy