【问题标题】:Swift unary operator with implicitly unwrapped optional具有隐式解包可选的 Swift 一元运算符
【发布时间】:2015-10-24 05:28:36
【问题描述】:

于是我问了this question,貌似是这个原因

var num:Int! = 0
num++

不起作用是因为 ++ 运算符采用 inout 参数,而隐式展开的选项不是。然而,在

var num:Int! = 0
num = num + 1

+ 运算符与隐式展开的可选项一起使用,这意味着二元运算符不需要 需要inout 参数。所以我的问题是,为什么一元和二元运算符有不同的参数要求?对我来说,能够将Int! 与仅二元运算符一起使用,但对所有内容都使用Int,这似乎有点愚蠢。

【问题讨论】:

    标签: swift optional unary-operator binary-operators


    【解决方案1】:

    为什么一元和二元运算符有不同的参数 要求?

    嗯,这不是一元与二元的问题。有与Int! 一起使用的一元运算符。例如:

    var i: Int! = 17
    var j = -i
    

    - 是一元运算符,它可以工作。问题又回到inout 的问题上。 ++ 的前缀和Int 的后缀运算符不适用于Int!,因为变量作为inout 传递(因为++ 除了返回一个值之外还修改了原始变量)。 inout 要求类型完全匹配。

    请注意,隐式展开的可选项仍然是可选项。

    var i: Int! = 17
    var k = i    // k has the type Int!
    var m = i!   // m has the type Int
    

    因此,将隐式展开的可选作为需要非可选类型的inout 变量传递是行不通的,因为inout 变量需要与预期的类型完全匹配,而IntInt! 是两个非常不同的类型。该变量必须显式解包,或者您需要提供一个采用可选类型的重载函数。

    你可能会问,为什么 Swift 不直接为你解开 Int! 并用 Int 调用 ++?好吧,++ 都修改了变量并返回了一个值。如果 Swift 解开 Int! 并使用 Int 调用 ++,那么返回的类型将是 Int。然后你会有人在 StackOverflow 上问,“为什么 var i: Int! = 17; var j = i++j 变成 Int 而不是 Int! ?”。要做到这一点,++ 需要在给定Int 时返回Int,并在给定Int! 时返回Int!。那么,重载函数需要什么。

    可以重载++ 并为Int! 制作++ 前缀和后缀函数:

    prefix func ++(inout x: Int!) -> Int! {
        return ++x!
    }
    
    postfix func ++(inout x: Int!) -> Int! {
        return x!++
    }
    
    var i: Int! = 17
    var j = ++i
    print("i = \(i), j = \(j)")  // "i = 18, j = 18"
    j = i++
    print("i = \(i), j = \(j)")  // "i = 19, j = 18"
    

    至于为什么 Swift 的设计者没有这样做,只有他们自己知道。

    【讨论】:

    • x++x = x + 1 快得多,这可能是他们没有按照您提供的方式实现它的原因。 x!++ 也可以代替 x++ 工作,我只是想知道为什么当变量被隐式解包时语言不会为您自动解包可选。
    • 他们可以随心所欲地实施。我只是想表明,消除做不到的想法是可能的。
    • 在那里,摆脱了x = x + 1,它无论如何都没有返回正确的后缀结果。
    • inout 变量类型必须完全匹配。 Int!Int 是两种截然不同的类型。如果他们想用Int! 支持++,他们可能会做我上面定义的事情。
    • 但是,如果inout 关键字如此严格,为什么他们首先需要它呢?他们不能只做postfix func ++(x:Int) -> Int {return x++} 之类的事情并完成,这样当参数被传递并且一切正常时就会发生解包?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-07
    • 2021-11-14
    • 1970-01-01
    • 2014-11-24
    • 1970-01-01
    • 1970-01-01
    • 2016-07-02
    相关资源
    最近更新 更多