【问题标题】:Semantics between optional and non-optional function parameters in Swift and best use casesSwift 中可选和非可选函数参数之间的语义以及最佳用例
【发布时间】:2014-08-16 23:53:35
【问题描述】:

我已经看到很多关于 Swift 中声明为 var a: String?var a: String! 的变量的讨论,前者是 String 类型的可选变量,而后者是隐式展开的可选 String。据我了解,当某些内容被隐式展开时,会假设可选值中已经包含一个值。为了使用语法a!.toInt(),必须像这样进行外部检查:

if a != nil {
   a!.toInt()
}

附带说明一下,最好将变量声明为可选类型,然后使用可选链解开该值(如果存在)。正在做:

if let numberString = a?.toInt() {
    numberString.toInt()
}

在实际应用中是否应该使用访问像a!.toInt() 这样的变量?在我看来,您似乎是在询问运行时错误。

现在是实际问题。我正在查看文档,特别是NSArray 上的enumerateObjectsUsingBlock,并且块参数是使用! 声明的。这是否意味着该函数的编写者假设块参数将是非零?如果是这样,在该函数内部,以下之间的语义区别是什么:

func someMethodWithBlock(block:((String!)-> Void)!) {
     var a = "Hello"
     block.(a) //first syntax example
     block?.(a)//2nd
     block!.(a)//3rd
}

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    在 Cocoa API 中几乎所有地方都使用隐式解包选项,因为它们被导入到 Swift 中——这是为了保持与 Obj-C 中普遍存在的指针语义的兼容性,而不需要 !s 和 ? s 到处都是。这就是NSArray 方法的块采用String! 参数的原因。

    在 Swift 中,由于您指定的原因,常规 Optional(Int? 等)在很大程度上更可取:它们不太容易出错。 Implicitly Unwrapped Optionals 主要用于仅在某些情况下使用,例如当您需要 pass self to a function before initialization is complete 时。 (如果你知道一个变量不是 nil,那么像 a!.toInt() 一样解开它就可以了。IUO 的危险在于它会写成 a.toInt(),对于读者来说这看起来完全安全,但实际上并非如此。)

    【讨论】:

    • 好的,太棒了!您是否认为使用 IOU(正在申请专利)的论点是,在 Apple 的 API 的情况下,它们会强制崩溃,从而使代码更易于调试?
    • 我不会说崩溃使它更易于调试。问题是错误何时发生。使用 IUO,如果您碰巧做出了错误的假设,就会出现运行时错误。使用常规 Optionals,编译器不允许你做任何假设,迫使你明确地说 !??
    • 嗯,可能不会更易于调试,而是保证在不满足某些条件时崩溃。我认为这里的不变量可能是正确的词。
    • 我宁愿我的编译器在编译时强制执行错误检查,而不是让我的程序在运行时“保证崩溃”,不是吗? ;)
    猜你喜欢
    • 2018-05-07
    • 1970-01-01
    • 2013-01-08
    • 2011-02-08
    • 2022-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多