打印可选变量

时间:2014-09-15 11:01:14

标签: swift

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

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.

12 个答案:

答案 0 :(得分:181)

您必须了解Optional的真正含义。许多Swift初学者认为var age: Int?意味着年龄是一个可能有也可能没有价值的Int。但这意味着年龄是一个可选的,可能会或可能不会持有Int。

description()功能中,您不打印Int,而是打印Optional。如果要打印Int,则必须打开Optional。您可以使用"可选绑定"打开一个可选:

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

如果你确定Optional包含一个对象,你可以使用"强制解包":

let a = age!

或者在您的示例中,由于您已在说明函数中对nil进行了测试,因此您只需将其更改为:

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

答案 1 :(得分:18)

可选意味着Swift不完全确定该值是否与类型相对应:例如,Int?意味着Swift并不完全确定该数字是否为Int。

  

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

1)如果您完全确定类型,可以使用感叹号强行打开它,如下所示:

// Here is an optional variable:

var age: Int?

// Here is how you would force unwrap it:

var unwrappedAge = age!

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

enter image description here

这不一定是安全的,所以这里有一种方法可以防止崩溃,以防您不确定类型和值:

  

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

2)隐式解包可选

 if let unwrappedAge = age {

 // continue in here

 }
  

请注意,展开的类型现在是 Int ,而不是 Int?

3)守卫声明

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

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

  

祝你的项目好运!

答案 2 :(得分:7)

<强>更新

只需使用me.age ?? "Unknown age!"即可。它适用于3.0.2。

旧答案

没有力量展开(没有马赫信号/崩溃,如果为零)另一种不错的方法是:

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

result["ip"] ?? "unavailable"也应该有效,但事实并非如此,至少在2.2中

当然,用适合你的东西替换“不可用”:“nil”,“not found”等

答案 3 :(得分:7)

出于测试/调试的目的,我经常希望将选项输出为字符串而不必总是测试nil值,因此我创建了一个自定义运算符。

我在阅读this answer in another question后进一步改进了事情。

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

答案 4 :(得分:4)

要解压缩可选使用age!而不是age。目前您正在打印可选值nil。这就是为什么它包裹着Optional

答案 5 :(得分:3)

age是可选类型:Optional<Int>因此,如果您将其与nil进行比较,则每次返回false都会返回false,如果它有值或者它没有。您需要打开可选项以获取值。

在您的示例中,您不知道它是否包含任何值,因此您可以使用此代码:

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

答案 6 :(得分:3)

我这样做是为了从另一个视图控制器打印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

答案 7 :(得分:3)

具有默认值时:

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

或名称为可选时:

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

答案 8 :(得分:1)

我在tableview单元格中获得了Optional(“String”)。

第一个答案很棒。并帮我弄明白了。这就是我做的,帮助像我这样的新秀。

因为我在自定义对象中创建了一个数组,所以我知道它总是会有第一个位置的项目,所以我可以强制将它打包到另一个变量中。然后使用该变量进行打印,或者在我的情况下,设置为tableview单元格文本。

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

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

答案 9 :(得分:0)

如果您只是想去掉 Optional(xxx) 之类的字符串,而是在某处打印某些值(例如日志)时得到 xxxnil,您可以将以下扩展添加到您的代码:

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

然后是下面的代码:

var x: Int?

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

x = 10

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

会给你:

x is nil
x is 10

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

答案 10 :(得分:0)

使用以下代码,您可以打印它或打印一些默认值。这就是我认为 XCode 通常推荐的内容

var someString: String?

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

答案 11 :(得分:-1)

这不是此问题的确切答案,而是造成此类问题的原因之一。 就我而言 我无法使用“ if let”和“ guard let”从字符串中删除Optional。

因此,使用 AnyObject 代替 Any 可以迅速从字符串中删除可选内容。

请参考链接以获取答案。

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