Почему каждый раз, когда я пытаюсь заставить пользователя ввести целое число в Swift, Xcode заставляет меня поставить "!"после переменной - PullRequest
0 голосов
/ 09 февраля 2019

Я работаю над кодом, в котором мне нужно получить 2 введенных пользователем целых числа и вывести меньшее.Я новичок в Swift, и каждый раз, когда я пытаюсь заставить пользователя ввести целое число, я получаю эту ошибку «Значение необязательного типа« String? »должен быть развернут в значение типа 'String' ".Я не понимаю, почему мне всегда нужно ставить "!"после readLine (), но это то, что заставляет меня делать.

print("Enter the first integer")
let int1 = Int(readLine()!)
print("Enter the second integer")
let int2 = Int(readLine()!)
let small_int = min(int1!, int2!) 
print("The smaller integer is", small_int)

Ответы [ 2 ]

0 голосов
/ 09 февраля 2019

Я рекомендую писать ваш код в оборонительной манере.Это включает в себя работу с неожиданными результатами.

Оба, readline() и Int() могут вернуть nil.Как уже объяснялось в другом ответе, readline возвращает nil, если вы достигли EOF.

Поэтому я рекомендую использовать оператор ?? для предоставления альтернативных значений для случаев сбоя.Например: let line = readline() ?? “”.

В качестве альтернативы, особенно внутри методов, вы можете захотеть выручить рано с guard и получить фактическую работу в конце метода с проверенными и ненулевыми входами.

Имея это в виду, ваш пример можно переписать так:

let line = readline() ?? “”
let int1 = Int(line) ?? 0
//...

Или как метод с защитой:

func smallerInteger() -> Int? {
   print("Enter the first integer")
   guard let line1 = readline() else {
      return nil
   }
   guard let int1 = Int(line1) else {
      return nil
   }
   print("Enter the second integer")
   guard let line2 = readline() else {
      return nil
   }
   guard let int2 = Int(line2) else {
      return nil
   }
   return min(int1, int2)
}

Конечно, это можно улучшитьвозвращая оба Int?а ошибка?как (Int?, Error?) или с последней версией Swift, а Result.

0 голосов
/ 09 февраля 2019

Как вы можете прочитать в документах :

Строка символов, прочитанная из стандартного ввода.Если EOF уже достигнут при вызове readLine (), результат равен nil.

... так что, упрощенно, readLine(strippingNewline:) не всегда должен возвращать значение и может также возвращатьnil (без значения), поэтому тип возвращаемого значения String?, который является необязательным типом, который говорит, что ваша константа равна String или nil

Если вам нужно получить необязательное значение, вы можете либопринудительное развертывание необязательного значения или проверка, существует ли значение, и если да, присвойте некоторую необязательную константу / переменную, используя необязательную привязку.То же самое вы можете сделать для инициализатора Int, который также может возвращать nil, поскольку не каждый String обязательно является целым числом

print("Enter the first integer")
let input1 = readLine()
print("Enter the second integer")
let input2 = readLine()

if let string1 = input1, let int1 = Int(string1), let string2 = input2, let int2 = Int(string2) {
    let small_int = min(int1, int2)
    print("The smaller integer is", small_int)
} else {
    print("Invalid input")
}

, в качестве альтернативы вы можете использовать значение по умолчанию, поэтому, если значение равно nil, вашеконстанте будет присвоено значение по умолчанию

print("Enter the first integer")
let int1 = Int(readLine() ?? "") ?? 0
print("Enter the second integer")
let int2 = Int(readLine() ?? "") ?? 0
let small_int = min(int1, int2) 
print("The smaller integer is", small_int)
...