2015-05-21 4 views
7

Согласно Swift - Converting String to Int, существует метод StringtoInt().Swift: Как преобразовать строку в UInt?

Но, нет toUInt() метода. Итак, как конвертировать String в Uint?

+0

для дополнительной детализации быстрой 2.x, String не содержит toInt() –

+0

@suraj Пожалуйста, прекратите добавлять «ИСН» тег на вопросы, которые непосредственно не связаны с прошивкой. Swift работает также с OS X и Linux, и эти вопросы могут применяться. Спасибо. – Moritz

+0

@ Eric D .. Спасибо за разъяснение по тегам. –

ответ

10

Обновление для Swift 2/Xcode 7 :

Начиная с Swift 2, все целые типы имеют конструкцию (failable)

init?(_ text: String, radix: Int = default) 

который заменяет toInt() метод String, поэтому нет пользовательских код не требуется больше для решения этой задачи:

print(UInt("1234")) // Optional(1234) 
// This is UInt.max on a 64-bit platform: 
print(UInt("18446744073709551615")) // Optional(18446744073709551615) 
print(UInt("18446744073709551616")) // nil (overflow) 
print(UInt("1234x")) // nil (invalid character) 
print(UInt("-12")) // nil (invalid character) 

Старый ответ на Swift 1.x:

Это выглядит несколько сложнее, но должно работать для всех номеров в полный диапазон UInt, и обнаружить все возможные ошибки правильно (например, переполнение или конечные недопустимые символы):

extension String { 
    func toUInt() -> UInt? { 
     if contains(self, "-") { 
      return nil 
     } 
     return self.withCString { cptr -> UInt? in 
      var endPtr : UnsafeMutablePointer<Int8> = nil 
      errno = 0 
      let result = strtoul(cptr, &endPtr, 10) 
      if errno != 0 || endPtr.memory != 0 { 
       return nil 
      } else { 
       return result 
      } 
     } 
    } 
} 

Примечания:

  • BSD, функция библиотеки strtoul используется для преобразования. endPtr установлен на первый «недопустимый символ» во входной строке, поэтому endPtr.memory == 0 должен быть удержанием, если все символов могут быть преобразованы. В случае ошибки преобразования глобальная переменная errno установлена ​​в на ненулевое значение (например, ERANGE для переполнения).

  • Испытание на знак минус необходим, потому что strtoul() принимает отрицательных чисел (которые преобразуются в число без знака с же битовой комбинацией).

  • Срочная строка преобразуется в строку C «за кулисами», когда переданных в функцию, принимающей параметр char *, таким образом можно было бы соблазна назвать strtoul(self, &endPtr, 0) (который является тем, что я сделал в первой версии этого ответа). Проблема в том, что созданная автоматически строка является временной и уже может быть недопустимой, когда strtoul() возвращает, так что endPtr не указывает на символ в строке ввода больше. Это произошло, когда я проверил код на игровой площадке. С self.withCString { ... } эта проблема не возникает, поскольку строка C действительна во время выполнения закрытия.

Некоторые тесты:

println("1234".toUInt()) // Optional(1234) 
// This is UInt.max on a 64-bit platform: 
println("18446744073709551615".toUInt()) // Optional(18446744073709551615) 
println("18446744073709551616".toUInt()) // nil (overflow) 
println("1234x".toUInt()) // nil (invalid character) 
println("-12".toUInt()) // nil (invalid character) 
+1

Было бы полезно, если бы downvoter оставил объяснительный комментарий. –

+0

Как преобразовать строку '0xff0000' в UInt? – TomSawyer

+0

@TomSawyer easy :-) let str = "0xff0000"; пусть p = UInt (String (str.characters.dropFirst (2)), radix: 16) // Необязательный (16711680) – user3441734

-1

просто использовать инициализации UINT в:

let someString = "4" 

UInt(someString.toInt()!) // 4 
+0

Это генерирует исключение __runtime__, если преобразование не выполнено – Antonio

2

Пожалуйста, для любви не врезаться, не используйте !, чтобы сделать это.

Это легко лавировать в map на конце toInt, чтобы преобразовать его в дополнительный UInt:

let str = "4" 
let myUInt = str.toInt().flatMap { $0 < 0 ? nil : UInt($0) } 

затем использовать the usual unwrapping techniques на myUInt.

И если вы обнаружите, что делаете это много:

extension String { 
    func toUInt() -> UInt? { 
     return self.toInt().flatMap { $0 < 0 ? nil : UInt($0) } 
    } 
} 

let str = "-4" 
if let myUInt = str.toUInt() { 
    println("yay, \(myUInt)") 
} 
else { 
    println("nuh-uh") 
} 

редактировать: в @MartinR указывает, в то время как сейф, это не извлечь весь диапазон возможных значений для UInt что Int Безразлично» t, см. два других ответа.

+0

Не должно ли оно быть flatMap() в первом? – oisdk

+1

Это (как и предыдущие два ответа) не будет работать, если число находится вне диапазона * подписанного * целого числа. –

+0

oops yes, вы абсолютно правы, я проверил дополнительную проверку до первого примера, но забыл внести изменения в карту –

3

Вы могли бы быть заинтересованы в безопасном решении аналогичного:

let uIntString = "4" 
let nonUIntString = "foo" 

extension String { 
    func toUInt() -> UInt? { 
     let scanner = NSScanner(string: self) 
     var u: UInt64 = 0 
     if scanner.scanUnsignedLongLong(&u) && scanner.atEnd { 
      return UInt(u) 
     } 
     return nil 
    } 
} 

uIntString.toUInt()  // Optional(4) 
nonUIntString.toUInt() // nil 

Надеется, что это помогает

// Edited следующего @Martin Р. внушению

+0

Одна проблема вот что это будет принимать мусор в конце строки, что не соответствует поведению аналогичной функции 'toInt()', то есть '' 4blah ".toInt()' возвращает 'nil', но' "4blah". toUInt() 'возвращает' 4' –

+0

... Это легко решить, добавив тест '&& scanner.atEnd'. Другая проблема заключается в том, что * переполнение * не обнаружено. –

+0

@Martin R. Обнаружение _overflow_ может быть добавлено для сканирования «Десятичный» и последующего выполнения соответствующих проверок. Это быстрое решение может работать для большинства распространенных случаев, избегая сбоев '!'. –

0

Использование Принудительный Unwrapping Необязательный Binding, чтобы убедиться, что строка может быть преобразован в UInt. например:

let string = "123" 
let number = UInt(string) //here number is of type *optional UInt* 

//Forced Unwrapping 

if number != nil { 
    //converted to type UInt 
} 
Смежные вопросы