打印可选variables

我正在尝试使用这些代码行

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. 

你必须明白什么是可选的。 许多Swift初学者认为var age: Int? 意味着年龄是一个可能或可能没有价值的Int。 但这意味着年龄是一个可选的,可能会或可能不会有一个整数。

description()函数内部,您不打印Int,而是打印Optional。 如果要打印Int,则必须打开“可选”。 您可以使用“可选绑定”来解包一个可选:

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

如果您确定可选项包含对象,则可以使用“强制解包”:

 let a = age! 

或者在你的例子中,因为你已经在description函数中有了一个nil的testing,所以你可以把它改成:

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

一个可选的手段,斯威夫特不完全确定,如果值对应的types:例如,诠释? 意味着Swift并不完全确定这个数字是否是Int。

要删除它,有三种方法可以使用。

1)如果您完全确定types,可以使用感叹号强制拆包,如下所示:

 // Here is an optional variable: var age: Int? // Here is how you would force unwrap it: var unwrappedAge = age! 

如果你强制打开一个可选的等于零,你可能会遇到这个崩溃错误:

在这里输入图像描述

这不一定安全,所以这里有一个方法可以防止在你不确定types和值的情况下崩溃:

方法2和方法3防止这个问题。

2)隐式解包可选

  if let unwrappedAge = age { // continue in here } 

请注意,解包types现在是Int ,而不是Int?

3)警戒声明

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

从这里,你可以继续使用解包variables。 如果您确定variables的types,请确保只强制展开(使用!)。

祝你的项目好运!

更新

只需使用me.age ?? "Unknown age!" me.age ?? "Unknown age!" 。 它在3.0.2中工作。

老答案

没有强制解包(没有马赫信号/崩溃,如果零)另一个好办法做到这一点将是:

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

result["ip"] ?? "unavailable" result["ip"] ?? "unavailable"应该有工作,但不是,至less不在2.2

当然,用适合你的“无”,“找不到”等代替“不可用”

打开可选的使用age! 而不是age 。 目前您打印的可选值可能nil 。 这就是为什么它与Optional包装。

在swift中Optional是在某些情况下可以nil东西。 如果你100%确定一个variable总是有一些值,不会返回nil ! 用variables强制展开它。

在其他情况下,如果你不太确定价值,那么添加一个if let block或guard来确保值存在,否则可能导致崩溃。

if let块:

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

guard声明:

如果条件不满足, guard是一个有条件的结构来返回控制权。

if let在许多情况下阻塞,我宁愿使用guard ,因为如果特定的值不存在,它允许我们返回function 。 就像有一个variables是存在的整数的函数一样,我们可以在守护语句中检查它,返回它不存在。 即;

 guard let abc = any_variable else { return } 

我们如果存在variables,我们可以在保护范围外的函数中使用'abc'。

为了testing/debugging的目的,我经常要输出可选的string,而不必经常testingnil值,所以我创build了一个自定义的运算符。

在另一个问题中读到这个答案后,我进一步改进了一些东西

 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 

集成其他人的协议思想使得它甚至可以与嵌套的optionals一起工作,这在使用可选的链接时经常发生。 例如:

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

age是可选的types: Optional<Int>所以如果你将它比较为零,它每次都返回false,如果它有一个值,或者它没有。 你需要打开可选的获取值。

在你的例子中,你不知道它是否包含任何值,所以你可以用它来代替:

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

我这样做是从另一个视图控制器打印string(属性)的值。

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 

看看guard声明:

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