【问题标题】:swift: forced type modifier "!" - why is (was) it used in UIKit API (now anachronistic)swift:强制类型修饰符“!” - 为什么(曾经)在 UIKit API 中使用它(现在不合时宜)
【发布时间】:2014-07-27 01:54:55
【问题描述】:

编辑:这个问题的目的是了解隐式可选运算符“!”的使用。在早期的 UIKit API 更新中,特别是如果一个函数被声明为返回一个预期为非可选的类型,为什么要使用可选的,如果它是可选的,为什么不使用可选的“?”操作员。 “!”的语义不过总是很清楚。

正如后来显示的那样,Apple 审核 API 以使可选性更加精确是一个问题,使用 ?对于真正的可选类型,并在它们实际上是非可选类型时使用非可选类型。这是对通常模棱两可的原始 Objective-C 签名的保留。


swift 文档解释了 !可选类型的拆箱运算符,

var optionalString : String? = "optional"
var regularString: String = optionalString!

但他们自己在类型定义上使用了它(字符串!),我找不到明确的解释。

例子:

func takesBang(value:String!) -> String {
    if !value {
        return "nil value, without the safe syntax"
    }

    return "This works"
}

var unsafe:String!
takesBang(unsafe) // yields "nil value, without the safe syntax"

字符串! type 不会强制对可选类型进行拆箱,但似乎只是消除了对可选语法 (?.) 的需求。 Apple 在他们自己的示例中使用了这一点,但它似乎只是否定了可选的安全(指针)机制。

谁能解释一下目的/动机?这似乎通常是不安全的,因为调用者不必检查或至少考虑它们的值。

【问题讨论】:

    标签: ios swift cocoa uikit


    【解决方案1】:

    语言参考指出,?! 在用于 var 声明时都只是语法糖(意味着它们在解析期间被编译器替换)。它们分别映射到 Optional<T> (?) 和 ImplicitlyUnwrappedOptional<T> (!)。

    虽然您必须对 Optional<T> 类型的变量使用 if let maybeNil = someVar? { ... } 语法,但您不必使用隐式展开的选项(正如名称已经暗示的那样)。正如https://stackoverflow.com/a/24071003/1599345 中的海报已经提到的那样,隐式展开的可选项旨在与 legacy Objective-C API 一起使用,因为这些 API 没有为 Swift 提供足够的信息。

    所以作为一个简短的回顾:

    var foo : SomeType? // should be read as var foo : Optional<SomeType>
    var bar : SomeType! // should be read as var bar : ImplicitlyUnwrappedOptional<SomeType>
    

    ?! 在处理变量中的实际值时的用法实际上是可以通过这种方式读取的映射,类似于上面的声明:

    foo?.somemethod() // if let maybeFoo = foo { maybeFoo.somemethod() }
    
    foo!.somemethod() /* # Yeah I know for sure, that this is NOT nil ever ever… just call `somemethod` and kill me at runtime if it doesn't work out.
    

    【讨论】:

      【解决方案2】:

      它通常是不安全的,但用于导入的 Objective-C API,它们以这种方式已经不安全,并且没有暴露足够的信息来决定它们应该是可选的还是非可选的。

      在非导入的 API 中,我不希望它被大量使用。

      【讨论】:

        【解决方案3】:

        事实证明,这只是 Apple 的疏忽,自 Beta 5 以来,他们一直在审核类并更新返回类型。

        来自 Beta 6 发行说明:

        “大量 Foundation API 已被审计为可选 一致性,删除大量隐式展开 来自其接口的选项。这阐明了可空​​性 它们的属性和参数/方法的返回值。这 自 Beta 5 以来一直在努力。”

        【讨论】:

        • 这个答案很有趣,但比! 作为ImplicitlyUnwrappedOptional&lt;T&gt; 的别名的解释要少。当我们知道一个值绝对应该是非零时(我们想要一个响亮的失败,我们也应该想要),那么使用它很有用。 @punycode 的回答更有用。
        • @ocodo,问题真的是,考虑到机制,为什么?答案仍然是现有 API 的语义在当时是未知或不清楚的,尽管据我所知,他们已经转向审计和澄清它。读过 Swift 的书后,我确实理解了这种机制——它们的含义以及它们是如何映射到底层可选类型的,只是不知道为什么它们会有一个不清楚的 API,但这似乎是一个过渡过程。
        • 感谢您的回复。我认为这个问题本身有点混乱,因为标题问,! 是什么,然后 OP 终于到了问“为什么?”的地步。在身体里。对于那些寻找定义的人来说,这个问题会弹出。所以我同意你的回答似乎确实解决了 OP,它没有反映人们搜索的问题。如果可以的话,我会撤回我的反对票,这种混乱显然不是你的错。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-11-20
        • 2014-05-12
        • 2013-06-25
        • 2021-06-29
        • 2023-03-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多