我开始使用swift和iOS,我遇到了疑问。让我们看看,有这个特殊的源代码:
if object?.stringValue != nil {
// send it to server
session.stopRunning()
sendQRCodeToApiServer(stringValueObtained: (object?.stringValue)!)
}
我明白在if object?.stringValue != nil
中? character意味着对象var可以是nil,因此它是可选的。但在内部界线:
sendQRCodeToApiServer(stringValueObtained: (object?.stringValue)!)
如果我不打开对象?.stringValue in()并带有感叹号(!),解释器会抛出一个错误,(如果我理解完美)意味着你确定结果有一个值并且它具有所需的类型,我的意思是,object.stringValue有一个值,IT是一个字符串。
嗯,我理解这完美,但编译器说的那样?而且!是必需的,首先说可能有一个值,第二个确定有一个值,........
我认为这种语法不一致且令人困惑,任何人都可以解释一下吗?
非常感谢你的时间
答案 0 :(得分:4)
选择性/强制展开/可选链接可能非常混乱。
根据经验,如果您发现必须“意外地”强制解包变量,那么绝对值得重新访问代码以故意解开您想要访问的变量。
有些人可能会说“ 每次使用!,婴儿独角兽死亡(可怕) ”
在第一行代码中,object是可选的
if object?.stringValue != nil {
除非您专门打开对象,否则必须使用?无论何时访问它或它的成员。这就是为什么当你稍后在方法调用 sendQRCodeToApiServer 中再次访问它时,你必须再次打开它。
当您打开可选项时,您为该变量的展开版本提供的名称就像该范围中的任何其他变量一样。当你打开一个可选的熊时,你正在积极减少数量吗?而且!出现在您的代码中,这样您就可以在6个月的时间内让自己更具可读性和可理解性,或者是下一个看到您代码的开发人员(嘿和独角兽爱你)。
让我们专门解开您想要使用的唯一变量(如果您有许多代码行访问对象成员然后我们可以解包对象 - 但是让我们坚持您的代码示例)
if let stringValueObtained = object?.stringValue {
// send it to server
session.stopRunning()
sendQRCodeToApiServer(stringValueObtained: stringValueObtained)
}
注意:
在if语句范围之外 stringValueObtained 不存在
我特意将已解包的变量命名为其预期用途
答案 1 :(得分:3)
语法强制 - 展开可选的链式表达式object?.stringValue
。由于object?.stringValue!
的结果不是可选的,因此您无法编写stringValue
,因此您需要添加括号(object?.stringValue)!
不幸的是,编译器建议语法,尽管它与object!.stringValue
实际上完全相同,但在检查后object
绝对不是nil
。
答案 2 :(得分:1)
使用带有'if let'的可选绑定
if let stringVal = object?.stringValue {
// send it to server
session.stopRunning()
sendQRCodeToApiServer(stringValueObtained: stringVal)
}
总是当你使用可选链接时,请使用if binding,因为可选链接总是返回一个可选值,无论该值容器的声明是否对象都是非可选的。
答案 3 :(得分:1)
sendQRCodeToApiServer(stringValueObtained: (object?.stringValue)!)
在这一行中,编译器会提示您解包,因为函数" stringValueObtained"需要一个非nill值作为参数。如果将函数的参数更改为可选,则不会提示您解包。 希望这会对你有所帮助。
答案 4 :(得分:1)
首先,让我们检查一下:
if object?.stringValue != nil {
如果object为nil或stringValue为nil,则条件为false。那是对象?.whatEver如果object为nil将返回nil,如果stringValue为nil,对象?.stringValue将返回nil。
sendQRCodeToApiServer(stringValueObtained: (object?.stringValue)!)
sendQRCodeToApiServer
需要字符串,但object?.stringValue
返回String?
,因此您需要解包。因为if条件,所以在这里打开是安全的。无论是通过对象!.stringValue(解包对象)还是(对象?.stringValue)! - 打开返回的值。
如果条件:
,则打开更好的选项if let stringVal = object?.stringValue {
// send it to server
session.stopRunning()
sendQRCodeToApiServer(stringValueObtained: stringVal)
}
答案 5 :(得分:0)
if object?.stringValue != nil
仅检查不是零。
所以,你需要展开价值。
建议使用此代码。
if let stringValue = object?.stringValue {
session.stopRunning()
sendQRCodeToApiServer(stringValueObtained: stringValue)
}