2017-06-19 11 views
5

Wydaje mi się, że powinien istnieć prosty sposób przeprowadzenia opcjonalnej konwersji z String na Int w Swift, ale nie mogę tego rozgryźć.Najprostszy sposób na przekonwertowanie opcjonalnego ciągu na opcjonalny Int w Swift

value to String? i potrzebuję zwrócić Int?.

Zasadniczo chcę, aby to zrobić, ale bez boilerplate:

return value != nil ? Int(value) : nil 

Próbowałem to, co wydaje się pasować do konwencji Swifta i byłoby miło i zwięzły, ale nie rozpoznaje składnię:

return Int?(value) 
+1

Jak o 'Int (wartość? "") ' – vacawama

+0

Tak, to jest lepsze. To dla mnie bardzo dziwne, że inicjator nie zaakceptuje opcji opcjonalnej i po prostu zwróciłby zero, gdyby jakikolwiek zero minęło. Przypuszczam, że system typu Swift miałby atak serca. – devios1

+0

Zaktualizowałem swoją odpowiedź rozszerzeniem Int, które właśnie to robi. – vacawama

Odpowiedz

5

można użyć nil zlewających operatora?? do otwierania String? i używać wartości domyślnej "" że znasz będzie produkować nil:

return Int(value ?? "") 

Innym podejściem: Int Inicjator że trwa String?

od opinii:

To bardzo dziwne mi się, że inicjator nie akceptuje opcjonalny i po prostu wrócić nil jeśli nil były przeszedł w

można utworzyć własny inicjator dla Int że właśnie to robi.

extension Int { 
    init?(_ value: String?) { 
     guard let value = value else { return nil } 
     self.init(value) 
    } 
} 

i teraz można po prostu zrobić:

var value: String? 
return Int(value) 
+1

Myślę, że to jest poprawne podejście i ma lepszą czytelność. –

+1

Podejście "zerowe" jest rzeczywiście czyste i czytelne, ale uważam, że warto zwrócić uwagę na podejście 'flatMap (_ :)' (w porównaniu do 'nil' koalescencyjny) nie wywoła połączenia typu "sure to fail" (przekazując literał '' "') do failable inicjatora 'Int' (przez' String'), jeśli 'wartość' jest' nil'. Z tego powodu, imho, podejście 'flatMap (_ :)' lub drugie wyżej (inicjator niestandardowy), preferuje koalescencję 'nil'. – dfri

+1

Niestandardowa metoda init mogłaby zostać nieco uproszczona do 'guard let value = value else {return nil}; self.init (wartość) ' –

8

można użyć metody flatMap() z Optional:

func foo(_ value: String?) -> Int? { 
    return value.flatMap { Int($0) } 
} 

Jeśli value == nil następnie flatMap wróci nil. W przeciwnym razie ocenia Int($0) gdzie $0 jest wartością rozpakowany, i zwraca wynik (który może być nil jeśli konwersja się nie powiedzie):

print(foo(nil) as Any)  // nil 
print(foo("123") as Any) // Optional(123) 
print(foo("xyz") as Any) // nil 
+0

Również 'map' robi to samo. – Sulthan

+0

@Sulthan: 'value.map {Int ($ 0)}' oszacowałoby zagnieżdżone opcjonalne, np. Opcjonalne (opcjonalne (123)) –

+0

@MartinR Ah tak, masz rację, nie zdawałem sobie sprawy, że opcjonalne wewnątrz! – Sulthan

2

z rozszerzeniem String nie należy się martwić o string == nil

extension String { 
    func toInt() -> Int? { 
    return Int(self) 
    } 
} 

Zastosowanie:

var nilString: String? 
print("".toInt())   // nil 
print(nilString?.toInt()) // nil 
print("123".toInt())  // Optional(123) 
Powiązane problemy