V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iOS 开发实用技术导航
NSHipster 中文版
http://nshipster.cn/
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
CocoaPods
http://cocoapods.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Design Guides and Resources
https://developer.apple.com/design/
Transcripts of WWDC sessions
http://asciiwwdc.com
Cocoa with Love
http://cocoawithlove.com/
Cocoa Dev Central
http://cocoadevcentral.com/
NSHipster
http://nshipster.com/
Style Guides
Google Objective-C Style Guide
NYTimes Objective-C Style Guide
Useful Tools and Services
Charles Web Debugging Proxy
Smore
machinemxy
V2EX  ›  iDev

被 Swift 的!和?搞死了😡😡😡

  •  1
     
  •   machinemxy ·
    machinemxy · 2015-09-07 11:34:46 +08:00 · 3974 次点击
    这是一个创建于 3373 天前的主题,其中的信息可能已经有所发展或是发生改变。

    其实我到现在也还没有理解他们具体应该用在什么场合下,教科书的解释都比较繁杂。于是我在写程序的时候常常遇到红色警报,修改建议让我加个“!”,但是加上后它又抱错建议我删除“!”。真是不明白“?”和“!”存在的意义啊,明明其他语言都没见过这样的语法。

    14 条回复    2015-09-17 22:12:56 +08:00
    dorentus
        1
    dorentus  
       2015-09-07 12:12:47 +08:00   ❤️ 5
    在 Swift 里面,关于 Optional 的 ? 和 ! 有以下几种用法:
    1 ) 用于类型定义, Type? 其实是 Optional<Type> 的简写,而 Type! 是一种特殊的 Optional 类型( Implicitly Unwrapped Optional )的写法
    2 ) ! 用于 Optional 类型变量名的后缀,用于强行解包(失败则触发 runtime error )
    3 ) ? 用于 Optional Chaining ,也是解包,不过失败的话不会触发 runtime error

    --------

    假设 A 是一个类型,那么 A? 类型(其实是 Optional<A>),其实是一个新的类型,它封装了两种可能性: nil 或者 A 的一个实例。

    使用 A? 类型的变量的时候(例如 var a: A?),需要进行判断来解出其中封装的 A 的一个实例值,或者 nil 。解包有好几种方式:
    1 ) 直接解,用叹号: let b = a!。如果 a 是 nil 的话,会触发 runtime error
    2 ) Optional Binding : if let b = a { /* 这里是有值的情况, b 的类型是 A */ } else { /* 这里是 nil 的情况 */ }
    3 ) Optional Chaining : a?.foo () /* 假设 A 定义了 func foo () -> B */,这时假如 a 是 nil ,那么方法调用不会发生;否则的话,方法 foo 被调用,返回一个 Optional<B> 即 B? 的类型的值。

    有一些情况,我们明确知道某个变量在我们使用的时候一定非 nil ,但是由于某些限制,无法在声明的时候就初始化(例如 ViewController 里面的 IBOutlet ),那么可以把它声明为 Implicitly Unwrapped Optional 类型,即: var a: A!。对于这种,我们可以像对待 A? 类型的变量一样,去做 Optional Binding 或者 Optional Chaining ,也可以把它当作非 Optional 的 A 类型变量一样直接用(但是如果在用的时候 a 是 nil ,那么会触发 runtime error )

    另外,不要在自己不确定在做什么的前提下去理会修改建议
    machinemxy
        2
    machinemxy  
    OP
       2015-09-07 12:32:07 +08:00
    @dorentus 谢谢您耐心的解答。?我已经理解了。关于!,根据您的解答,我的理解是它有两种用法。
    第一种是 let b = a! 就是将原本是 A?类型的变量 a 赋值给 b ,然后根据类型推断, b 成为了 A 类型(而不是 A?)。
    第二种是 let a = A!,这样定义的话, a 就既可以像 A 类型那样使用,又可以像 A?类型这样使用了。
    不知我的理解是否有误。
    dorentus
        3
    dorentus  
       2015-09-07 12:52:33 +08:00
    @machinemxy
    假如 a 是 A?; let b = a! 的话,其实 b 是 A! 类型。

    let a: A! 来定义的话,这个 a 直接就是 A! 类型。

    A! 类型的变量,在用的时候可以不解包直接当成和 A 类型的一样用(但是如果值是 nil 的话就直接闪退了)。然后它也可以当作 A? 类型那样,去手动使用 Optional Binding 或者 Chaining 来解包去判断它是 nil 还是有值。
    dorentus
        4
    dorentus  
       2015-09-07 12:59:15 +08:00
    @dorentus
    我弄错了

    直接 let b = a! 解包的话,这个 b 确实是 A 类型了(如果 a 是 nil 的话,出错是在 b 被赋值之前发生的)
    machinemxy
        5
    machinemxy  
    OP
       2015-09-07 13:11:16 +08:00
    @dorentus 多谢,多亏了你,我才弄懂了这几个概念。
    fhefh
        6
    fhefh  
       2015-09-07 13:34:42 +08:00
    mark 学习了~
    Majirefy
        7
    Majirefy  
       2015-09-07 13:39:34 +08:00
    学习学习,的确也不太懂~~
    Bijiabo
        8
    Bijiabo  
       2015-09-07 14:16:25 +08:00
    学习>_<
    lk920724
        9
    lk920724  
       2015-09-07 14:18:55 +08:00   ❤️ 1
    wezzard
        10
    wezzard  
       2015-09-07 14:22:42 +08:00   ❤️ 1
    忠告:不要面向黑盒子編程
    machinemxy
        11
    machinemxy  
    OP
       2015-09-07 14:34:24 +08:00
    @lk920724 噗…
    XueSeason
        12
    XueSeason  
       2015-09-07 22:40:32 +08:00
    @wezzard 然而不久 Swift 就开源了。
    wezzard
        13
    wezzard  
       2015-09-08 07:28:07 +08:00
    @XueSeason 我說的面向黑盒子編程是指不看編程語言說明書,不搞清楚機制,根據 IDE 的提示來編程。
    DingSoung
        14
    DingSoung  
       2015-09-17 22:12:55 +08:00
    还好吧 ,我解析 XML 时被 try catch 整了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2590 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 04:16 · PVG 12:16 · LAX 20:16 · JFK 23:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.