Printing optional variable

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

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())

Above code produces as follow

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

My question is why there is Optional (18) there, how can I remove the optional and just printing

Daniel is 18 years old.
88173 次浏览

要取消包装,可以使用 age!而不是 age。目前您正在打印可选的值,可以是 nil。这就是为什么它包裹着 Optional

age是可选的类型: Optional<Int>,所以如果你比较它和 nil,如果它有值或者没有值,它每次都返回 false。您需要展开可选项以获取值。

In your example you don't know is it contains any value so you can use this instead:

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

你必须明白什么是选择权。许多 Swift 初学者认为 var age: Int?表示年龄是一个 Int,它可能有值,也可能没有值。但它意味着 age 是一个可选项,它可能包含 Int,也可能不包含 Int。

description()函数中,不打印 Int,而是打印可选项。如果要打印 Int,则必须展开“可选”。您可以使用“可选绑定”来展开可选的:

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

如果你确定“可选”包含一个对象,你可以使用“强制展开”:

let a = age!

Or in your example, since you already have a test for nil in the description function, you can just change it to:

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

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

  1. 如果你非常确定这种类型,你可以使用一个叹号来强制打开它,像这样:

    //这里有一个可选的变量:

    Int?

    // Here is how you would force unwrap it:

    年龄 = 年龄!

如果您强制打开一个可选项并且它等于 nil,您可能会遇到这个崩溃错误:

enter image description here

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

方法二、三对这一问题进行防范。

  1. 隐式取消包装的可选项

    如果让 unwrappdAge = age {

    //继续在这里

    }

注意,取消包装类型现在是 内景,而不是 Int?

  1. 警卫的证词

    年龄 = 其他年龄 //继续在这里 }

从这里开始,您可以继续使用取消包装的变量。确保只强制打开(使用!),如果您确定变量的类型。

祝你的项目好运!

I did this to print the value of string (property) from another view controller.

ViewController.swift

var testString:NSString = "I am iOS Developer"

Second ViewController 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

更新

简单地使用 me.age ?? "Unknown age!",它在3.0.2中工作。

老答案

如果没有强制展开(没有马赫数信号/如果没有崩溃) ,另一个不错的方法是:

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

result["ip"] ?? "unavailable"也应该有工作,但它没有,至少在2.2中没有

当然,用任何适合你的词来替换“不可用”: “无”、“未找到”等等

看看 guard的声明:

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

在快速 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 over if let块,因为它允许我们在不存在特定值的情况下返回 function。 就像有一个函数,其中的一个变量是整数存在,我们可以检查它在约束语句,并返回它不存在。 I-e;

guard let abc = any_variable else { return }

如果变量存在,我们可以在保护范围之外的函数中使用“ abc”。

出于测试/调试的目的,我经常希望将选项作为字符串输出,而不必总是测试 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

我正在桌面视图单元格中获取可选项(“ String”)。

第一个答案很好。帮我想明白了。我是这么做的,帮助像我这样的菜鸟。

因为我要在自定义对象中创建一个数组,所以我知道它总是在第一个位置有项,所以我可以强制将其展开为另一个变量。然后使用该变量打印,或者在我的例子中,设置为 tableview 单元格文本。

let description = workout.listOfStrings.first!
cell.textLabel?.text = description

现在看起来很简单,但我花了一段时间才弄明白。

This is not the exact answer to this question, but one reason for this kind of issue. 对我来说, I was not able to remove Optional from a String with "if let" and "guard let".

因此,使用 AnyObject而不是 Any来删除快速字符串中的可选项。

答案请参考链接。

https://stackoverflow.com/a/51356716/8334818

当具有默认值时:

print("\(name) is \(age ?? 0) years old")

或者名字是可选的:

print("\(name ?? "unknown") is \(age) years old")

如果您只是想去掉像 Optional(xxx)这样的字符串,而是在打印某些值(比如日志)时得到 xxxnil,那么您可以在代码中添加以下扩展:

extension Optional {
var orNil: String {
if self == nil {
return "nil"
}
return "\(self!)"
}
}

Then the following code:

var x: Int?


print("x is \(x.orNil)")


x = 10


print("x is \(x.orNil)")

会给你:

x is nil
x is 10

属性命名(orNil)显然不是最好的,但我想不出更清楚的东西。

使用下面的代码,您可以打印它或打印一些默认值

var someString: String?


print("Some string is \(someString ?? String("Some default"))")