为什么这个基本类型扩展不起作用?

时间:2015-05-05 22:14:07

标签: swift generics extension-methods

尝试使用扩展程序,但是在使用以下内容时遇到问题:

let value = -13
abs(value)

extension Int {
    var abs:Int {
        return abs(self) // -> Cannot invoke 'abs' with an argument list of type '(Int)'
    }
}

value.abs

编译错误很奇怪,因为它可以使用abs()作为参数在上面直接运行Int函数。我猜我还有一些灯泡可以触发仿制药。启发我。

4 个答案:

答案 0 :(得分:4)

Swift编译器感到困惑的是,您使用abs变量作为函数,它无法做到。现在,您可以查看所有答案并重命名变量,但这些并不能让您深入了解Swift函数的工作原理。

Swift自动导入Swift框架,在框架中定义其静态函数。要使用这些函数,通常不需要指定它来自框架,但在这种情况下,您应该指定要使用abs框架中的Swift方法。

所有解释之后,这是你的代码,它将起作用:

let value = -13
abs(value)

extension Int {
    var abs: Int {
        return Swift.abs(self)
    }
}

value.abs

答案 1 :(得分:2)

它似乎只是一个呼叫解决问题。这将有效:

let value = -13
abs(value)


extension Int {
    var abs1:Int {
        return abs(self)
    }
}

value.abs1

这也可行:

extension Int {
    var abs:Int {
        return self < 0 ? -self : self
    }
}

value.abs

答案 2 :(得分:2)

这里的问题是您正在扩展Int以添加名为abs的变量 - 这也是您正在呼叫的函数的名称。

当您尝试在abs()上调用函数Int时,它会看到您创建的变量abs并且因为它认为您尝试返回该变量而感到困惑不明白你为什么要给它发一个参数。

如果您将变量重命名为absoluteValue或其他任何内容,它应该可以正常工作。

let value = -13
abs(value)

extension Int {
var absoluteValue:Int {
        return abs(self)
    }
}

value.abs

更新:正如其他人所说,您还可以通过在abs框架内显式调用该函数来解决使用Swift的歧义。这应该与上述解决方案一样有效。

let value = -13
abs(value)

extension Int {
var abs:Int {
        return Swift.abs(self)
    }
}

value.abs

虽然,就个人而言,我仍然会像第一个示例中那样将我的新功能重命名为absoluteValue,以便明确表示在使用Swift.abs()时没有调用abs变量

答案 3 :(得分:0)

由于原始两个答案的方向(全局自由函数和我定义的var之间的冲突),它们必须消除歧义。我可以使用abs()命名空间正确地对内部Swift进行范围限定,而不是自己进行abs的内联实现或强制使用其他名称。

extension Int {
    var absoluteValue:Int {
        return Swift.abs(self)
    }
}

这给了我两全其美(IMO)。