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
ldehai
V2EX  ›  iDev

Swift optional 类型真烦,写了一个月 swift 了还有点搞不清?和!

  •  
  •   ldehai ·
    ldehai · 2016-09-27 11:47:08 +08:00 · 6334 次点击
    这是一个创建于 3008 天前的主题,其中的信息可能已经有所发展或是发生改变。
    41 条回复    2016-11-04 11:01:52 +08:00
    ChefIsAwesome
        1
    ChefIsAwesome  
       2016-09-27 11:51:41 +08:00
    貌似就是个 maybe monad 。真羡慕自带这种东西的语言。
    isweal
        2
    isweal  
       2016-09-27 11:56:04 +08:00
    let advertCount = self.cvsAdvertModel?.infos?.ref(0)?.imgs?.count ?? 0
    感受一下
    ldehai
        3
    ldehai  
    OP
       2016-09-27 11:57:50 +08:00
    @isweal 太烧脑子了
    xiaoc19
        4
    xiaoc19  
       2016-09-27 11:59:23 +08:00   ❤️ 1
    你不如花个 5 分钟仔细思考他们的区别 再写。。。。
    其实很简单
    congeec
        5
    congeec  
       2016-09-27 12:08:41 +08:00 via iPhone   ❤️ 1
    你要是用 rust ,写一大堆 match, unwrap, try!()就知道有多烦了。这是好东西
    kera0a
        6
    kera0a  
       2016-09-27 12:19:46 +08:00   ❤️ 1
    我一开始也挺烦这些的,现在用习惯了发现是神器啊
    比如这位兄弟提到的例子
    @isweal
    let advertCount = self.cvsAdvertModel?.infos?.ref(0)?.imgs?.count ?? 0

    如果没有 optional ,取 advertCount 要这样
    if(self.cvsAdvertModel != nil ){
    if( ...infos? != nil){
    if( ...ref(0) != nil ){
    if
    if
    }
    }
    }

    而 optional 写法
    if let advertCount = self.cvsAdvertModel?.infos?.ref(0)?.imgs?.count {

    }
    else{
    let advertCount = 0;
    }

    当然还有其他很多用法,理解下其实挺爽的
    ldehai
        7
    ldehai  
    OP
       2016-09-27 12:29:14 +08:00
    其实我就是懒,刚硬着头皮去看了 apple 的文档,有点开窍了。磨刀不误砍柴功,真理 https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html
    yjxjn
        8
    yjxjn  
       2016-09-27 12:42:10 +08:00   ❤️ 1
    stackoverflow 上面有关于 optional 的解释,仔细看看,多读几遍,今天看不懂,明天继续看,总会看懂的,当初我也没明白,感觉傻逼一样的类型,用顺手之后,发现真的很好用!
    SOW 地址:
    http://stackoverflow.com/questions/24003642/what-is-an-optional-value-in-swift
    zythum
        9
    zythum  
       2016-09-27 13:04:28 +08:00
    这个挺好的呀。真的是个好东西
    zacard
        10
    zacard  
       2016-09-27 13:15:12 +08:00
    好用的语法糖,超甜
    zhuangzhuang1988
        11
    zhuangzhuang1988  
       2016-09-27 13:25:08 +08:00
    C#早就有了..
    Troevil
        12
    Troevil  
       2016-09-27 13:33:12 +08:00
    你是没看到 java 的 optional , 就算现在有了 optional 类型 还是惨不忍睹 超级难用
    ldehai
        13
    ldehai  
    OP
       2016-09-27 13:44:45 +08:00
    @zythum 我是觉得它可以设计的更友好一点,不要我去想着这是个 optional ,我要加?才行。要是编译器自己能自动判断最好了。
    subpo
        14
    subpo  
       2016-09-27 13:58:15 +08:00
    看起来 ruby 的?和!不同
    zhuangzhuang1988
        15
    zhuangzhuang1988  
       2016-09-27 13:59:06 +08:00
    推荐看这个 http://codon.com/refactoring-ruby-with-monads
    怎么把
    这个

    简化成


    怎么把
    这个

    简化成


    就知道 optional(monad)的作用了..
    ldehai
        16
    ldehai  
    OP
       2016-09-27 14:07:24 +08:00
    @zhuangzhuang1988 这个设计的好,不用加任何?和!,没心理负担
    jackisnotspirate
        17
    jackisnotspirate  
       2016-09-27 14:17:35 +08:00   ❤️ 1
    「不要我去想着这是个 optional ,我要加?才行」现在 Swift 3 里面 ! 表示 Implicitly Unwrapped Optional, 就是你想要的了。
    tabris17
        18
    tabris17  
       2016-09-27 14:18:50 +08:00
    新手觉得烦,老鸟觉得简直救命
    xjbeta
        19
    xjbeta  
       2016-09-27 15:41:24 +08:00
    反正别用强制解包(万恶之源 各种崩溃都和这玩意有关) 多写个 if let 。。。。
    littleshy
        20
    littleshy  
       2016-09-27 15:49:20 +08:00
    函数式语言的特性,用习惯了就爽!
    shyling
        21
    shyling  
       2016-09-27 16:44:43 +08:00
    data Optional = Some a
    | None

    个人感觉其实 a?.b?.c?? d 没太大的好处。。。
    def try(default=nil)
    begin
    yield
    rescue
    default
    end
    -->
    try(default) do
    a.b.c.d.e
    end
    也很好用呀~
    一个 CPS ,用在异步上配合自带 do-notation(haskell)/for(scala)语法才是正道=-=
    freshfish
        22
    freshfish  
       2016-09-27 16:46:46 +08:00
    @zhuangzhuang1988 Ruby2.0 可以这么写
    ```ruby
    a&.b&.c&.d
    ```

    2.0 以前可以这么写
    ```ruby
    a.try(:b).try(:c).try(:d)
    ```
    shimanooo
        23
    shimanooo  
       2016-09-27 16:56:05 +08:00
    type?是个必要概念。
    type!,即 Implicitly Unwrapped Optional ,就是个语法糖。
    建议上手尽量用显示 unwrap 。

    variable!和 type!不一样,这个有时侯不得不用。
    fengmenggaokao
        24
    fengmenggaokao  
       2016-09-27 18:12:21 +08:00
    摘自 scala(swift 抄的多好就不说了)
    option[A] 一个容器,要么是 None 要么是 Some 。 Some 可以看作一个安全的 List 集 合,主要是安全,一些方法(foreach 、 filter)这样就不用判断是否为非空,在 匹配模式中使用 Some 就可以过滤掉为 None 的元素
    crashX
        25
    crashX  
       2016-09-27 18:38:26 +08:00
    我们组刚工作的开发都懂。虽然不懂 monad 啥的。
    ldehai
        26
    ldehai  
    OP
       2016-09-27 19:45:11 +08:00
    tairan2006
        27
    tairan2006  
       2016-09-27 21:09:59 +08:00
    这玩意儿 C++里面不是好多年前就有了。。 boost::optional ?
    或者 Haskell 里面的 Maybe a = Just a | Nothing
    wizardforcel
        28
    wizardforcel  
       2016-09-27 22:30:01 +08:00
    来看看 java 版的:

    advertCount = Optional.of(self).map(o -> o.cvsAdvertModel).map(o -> o.infos).map(o -> o.ref(0)).map(o -> o.imgs).map(o -> o.count).orElse(0);
    ldehai
        29
    ldehai  
    OP
       2016-09-27 23:53:37 +08:00
    @wizardforcel 吐了
    Perry
        30
    Perry  
       2016-09-28 00:37:30 +08:00 via iPhone
    @ldehai Xcode 大多数情况会帮你自动加 不然会提醒你
    ldehai
        31
    ldehai  
    OP
       2016-09-28 00:41:19 +08:00
    @Perry 主要看着感觉不美观,多希望 swift 里把这两个符号给去掉
    yjxjn
        32
    yjxjn  
       2016-09-28 09:54:35 +08:00
    @Perry 有 warning ,不过你不加有时候写个 if else 的 null 的判断也行。。。。不过感觉还是没有?方便。。
    webfrogs
        33
    webfrogs  
       2016-09-28 10:41:51 +08:00
    不要使用 !
    不要使用 !
    不要使用 !
    jackisnotspirate
        34
    jackisnotspirate  
       2016-09-28 11:29:46 +08:00
    @webfrogs 你想说的是不要强制解包吧, Swift 3 里面 ! 有新变化
    yongSir
        35
    yongSir  
       2016-09-28 16:21:08 +08:00
    其实刚开始也不习惯
    但习惯了就是神器啊

    但如果出现像 self.cvsAdvertModel?.infos?.ref(0)?.imgs?.count ?? 0 这样的
    不妨去考虑一下 model 的结构
    不要弄的太深了

    原则是不要轻易使用‘!’
    多使用 if let a = xxx 或者 guard 语句代替
    free9fw
        36
    free9fw  
       2016-09-28 16:41:41 +08:00
    多使用 guard , swift 能做到这样类型安全已经很优秀了,理解了其实很简单,对比 OC ,才是一堆坑
    beordle
        37
    beordle  
       2016-09-28 19:18:01 +08:00
    真的花一点时间即可理解...
    sharpy
        38
    sharpy  
       2016-09-30 15:58:04 +08:00
    就是语法糖 Optional<T> ,不这样写的话,每一个 Optional 都得匹配一下,
    iAugus
        39
    iAugus  
       2016-10-18 00:42:46 +08:00
    用 "!" 强制解包你得 100% 确定这个值不为 nil ,否则得话用 "?" 加 "guard / if "判断一下。所以原则上不要轻易使用 "!"
    laoyur
        40
    laoyur  
       2016-11-04 09:51:24 +08:00
    也许是还没习惯的缘故,每次写的时候都很烧脑,一般都要依靠 Xcode 来更正
    不仅仅是打个?或!那么简单的,还有 as ? 、??、必须加括号后再加问号(xxx?.yyy) ?、 try !等等各种形式
    ldehai
        41
    ldehai  
    OP
       2016-11-04 11:01:52 +08:00
    @laoyur 有时候 Xcode 更正的是错的,还得自己改回去:(
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2449 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 15:47 · PVG 23:47 · LAX 07:47 · JFK 10:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.