Печать дополнительной переменной

Я пытаюсь с этими строками кода

class Student {
    var name: String
    var age: Int?

    init(name: String) {
        self.name = name
    }

    func description() -> String {
        return age != nil ? "\(name) is \(age) years old." : "\(name) hides his age."
    }
}

var me = Student(name: "Daniel")
println(me.description())
me.age = 18
println(me.description())

Выше код выводится следующим образом

Daniel hides his age.
Daniel is Optional(18) years old.

Мой вопрос в том, почему есть опция (18), как я могу удалить дополнительную и просто распечатку

Daniel is 18 years old.

Ответ 1

Вы должны понять, что действительно есть. Многие начинающие Swift считают, что var age: Int? означает, что возраст - это Int, который может иметь или не иметь значения. Но это означает, что возраст является необязательным, который может содержать или не содержать Int.

Внутри вашей функции description() вы не печатаете Int, но вместо этого вы печатаете опцию. Если вы хотите распечатать Int, вам необходимо развернуть опцию. Вы можете использовать "необязательное связывание", чтобы развернуть необязательный параметр:

if let a = age {
 // a is an Int
}

Если вы уверены, что объект "Дополнительно" содержит объект, вы можете использовать "принудительное разворачивание":

let a = age!

Или в вашем примере, поскольку у вас уже есть тест для nil в функции описания, вы можете просто изменить его на:

func description() -> String {
    return age != nil ? "\(name) is \(age!) years old." : "\(name) hides his age."
}

Ответ 2

Необязательный означает, что Swift не совсем уверен, соответствует ли значение типу: например, Int? означает, что Swift не совсем уверен, является ли число Int.

Чтобы удалить его, вы можете использовать три метода.

1) Если вы абсолютно уверены в типе, вы можете использовать восклицательный знак, чтобы развернуть его, например:

// Here is an optional variable:

var age: Int?

// Here is how you would force unwrap it:

var unwrappedAge = age!

Если вы принудительно распакуете опцию, и она равна нулю, вы можете столкнуться с этой ошибкой при сбое:

введите описание изображения здесь

Это не обязательно безопасно, поэтому здесь метод, который может предотвратить сбой, если вы не уверены в типе и значении:

Методы 2 и три защищают эту проблему.

2) Неявно освобожденный необязательный

 if let unwrappedAge = age {

 // continue in here

 }

Обратите внимание, что развернутый тип теперь Int, а не Int?.

3) Заявление охранника

 guard let unwrappedAge = age else { 
   // continue in here
 }

Отсюда вы можете перейти и использовать развернутую переменную. Убедитесь, что вы принудительно разворачиваете (с помощью!), Если вы уверены в типе переменной.

Удачи вам в вашем проекте!

Ответ 3

Обновление

Просто используйте me.age ?? "Unknown age!". Он работает в версии 3.0.2.

Старый ответ

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

(result["ip"] ?? "unavailable").description.

result["ip"] ?? "unavailable" тоже должен работать, но это не так, а не в 2.2 по крайней мере

Конечно, замените "недоступным" на то, что вам подходит: "nil", "not found" и т.д.

Ответ 4

Для развертывания необязательно используйте age! вместо age. В настоящее время вы печатаете необязательное значение, которое может быть nil. Вот почему он обернут Optional.

Ответ 5

В быстром Optional есть что-то, что может быть nil в некоторых случаях. Если вы на 100% уверены, что variable всегда будет иметь какое-то значение и не вернет nil, добавьте ! с переменной, чтобы принудительно развернуть его.

В противном случае, если вы не уверены в значении, добавьте блок if let или guard, чтобы убедиться, что это значение существует, иначе оно может привести к сбою.

Для блока if let:

if let abc = any_variable {
 // do anything you want with 'abc' variable no need to force unwrap now.
}

Для оператора guard:

guard - условная структура, возвращающая управление, если условие не выполнено.

Я предпочитаю использовать guard над блоком if let во многих ситуациях, поскольку он позволяет нам вернуть function, если определенное значение не существует. Например, когда существует функция, в которой переменная является неотъемлемой частью, мы можем проверить ее в операнде, а возврат ее не существует. I-е;

guard let abc = any_variable else { return }

Мы, если существует переменная, мы можем использовать 'abc' в области внешней защиты.

Ответ 6

Для тестирования/отладки я часто хочу выводить опционы как строки без необходимости тестировать значения nil, поэтому я создал пользовательский оператор.

Я улучшил ситуацию даже после прочтения этого ответа в другом вопросе.

fileprivate protocol _Optional {
    func unwrappedString() -> String
}

extension Optional: _Optional {
    fileprivate func unwrappedString() -> String {
        switch self {
        case .some(let wrapped as _Optional): return wrapped.unwrappedString()
        case .some(let wrapped): return String(describing: wrapped)
        case .none: return String(describing: self)
        }
    }
}

postfix operator ~? { }
public postfix func ~? <X> (x: X?) -> String {
    return x.unwrappedString
}

Очевидно, что оператор (и его атрибуты) можно настроить по своему вкусу, иначе вы можете сделать его функцией. В любом случае, это позволяет написать простой код следующим образом:

var d: Double? = 12.34
print(d)     // Optional(12.34)
print(d~?)   // 12.34
d = nil
print(d~?)   // nil

Интеграция идеи протокола другого парня сделала так, что это даже работает с вложенными опциями, которые часто возникают при использовании дополнительной цепочки. Например:

let i: Int??? = 5
print(i)              // Optional(Optional(Optional(5)))
print("i: \(i~?)")    // i: 5

Ответ 7

age является необязательным типом: Optional<Int>, поэтому, если вы сравниваете его с nil, он возвращает false каждый раз, если он имеет значение или нет. Вам нужно развернуть опцию, чтобы получить значение.

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

if let myAge = age {
    // there is a value and it currently undraped and is stored in a constant
}
else {
   // no value
}

Ответ 8

Я сделал это, чтобы напечатать значение string (property) с другого контроллера представления.

ViewController.swift

var testString:NSString = "I am iOS Developer"

SecondViewController.swift

var obj:ViewController? = ViewController(nibName: "ViewController", bundle: nil)
print("The Value of String is \(obj!.testString)")

Результат:

The Value of String is I am iOS Developer

Ответ 9

Обратите внимание на инструкцию guard:

for student in class {
    guard let age = student.age else { 
        continue 
     }
    // do something with age
}