首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么Swift操作符重载需要是类型方法?

为什么Swift操作符重载需要是类型方法?
EN

Stack Overflow用户
提问于 2021-10-13 14:20:34
回答 3查看 178关注 0票数 1

斯威夫特语言指南显示,如下所示的运算符方法必须编写为static

代码语言:javascript
运行
复制
struct Vector2D {
    var x = 0.0, y = 0.0
}

extension Vector2D {
    static func + (left: Vector2D, right: Vector2D) -> Vector2D {
        return Vector2D(x: left.x + right.x, y: left.y + right.y)
    }
}

let vector = Vector2D(x: 3.0, y: 1.0)
let anotherVector = Vector2D(x: 2.0, y: 4.0)
let combinedVector = vector + anotherVector

如果删除static关键字,它将导致编译错误:

在“Vector2D”扩展中声明的运算符“+”必须是“静态”

提出这一要求的原因是什么?为什么我们不能把它写成一个非静态的方法呢?

我可以盲目地接受“这就是它的方式”。但是我想了解为什么这是必要的,这样我才能更好地理解Swift语言。我一直未能找到提出这项规定的具体原因。

如果我不得不猜测,我猜想Swift中的默认操作符是作为类型方法实现的,因此我们的自定义操作符也必须是静态的。但这纯粹是猜测。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-10-13 14:55:43

这对我来说很有道理。二进制运算符以两个对象作为参数,并返回结果。

这样的运算符不属于任何对象的实例。它是类中的一个静态方法。对于+类型的Vector2D方法的示例,它是一个知道如何将2个Vector2D对象添加到一起的方法。

您不会在+实例上调用Vector2D方法。您说:“嗨,Vector2D类型,我如何将您的类型的两个实例相加?

您是在“与”类“交谈”,而不是类的实例。

编辑:

如果是实例方法,则必须将add操作符表示为一个操作数的消息:

代码语言:javascript
运行
复制
extension Vector2D {
    func addVector(_: Vector2D) -> Vector2D {
        // Code to sum two vectors
    }
}

你会把它叫做

代码语言:javascript
运行
复制
sum = aVector.addVector(anotherVector)
票数 1
EN

Stack Overflow用户

发布于 2021-10-13 15:09:41

这是一种语言设计选择,不同的语言决定了不同的对立面: C++不允许静态运算符,而C#要求它们是静态的,就像Swift一样。

对我来说,让操作符静止的最令人信服的理由是对称。

让我们暂时将+替换为名为plus的函数。如果plus是静态的,则将其称为Vector2D.plus(vector, anotherVector),这将与调用Vector2D.plus(anotherVector, vector)相同。

如果它是实例成员,则将其称为vector.plus(anotherVector),这可能与anotherVector.plus(vector)相同,也可能不相同。也就是说,如果vectornil,则vector.plus(anotherVector)肯定是nil,而anotherVector.plus(vector)将等于anotherVector

类似地,操作符+是静态的,允许这个vector + anotherVector == anotherVector + vector,而不考虑两个向量的nil状态。

票数 1
EN

Stack Overflow用户

发布于 2021-10-13 16:41:20

操作人员不必是静态的。它们也可以是全局函数。

代码语言:javascript
运行
复制
struct Vector2D {
    var x = 0.0, y = 0.0
}

func + (left: Vector2D, right: Vector2D) -> Vector2D {
    return Vector2D(x: left.x + right.x, y: left.y + right.y)
}

let vector = Vector2D(x: 3.0, y: 1.0)
let anotherVector = Vector2D(x: 2.0, y: 4.0)
let combinedVector = vector + anotherVector

如果您问为什么它们不能是实例方法,那么,因为实例方法需要一个额外的Vector2D实例来调用。这个实例,加上+需要的两个参数,意味着您需要3个Vector2D来调用+,这没有多大意义.

另一方面,营办商可能是这样设计的:

代码语言:javascript
运行
复制
extension Vector2D {
    func +(right: Vector2D) -> Vector2D { ... }
}

其中,二进制运算符不是对两个参数进行操作,而是在self和单个参数上操作。这与Kotlin的操作符重载设计类似。

据我所见,Swift中没有任何东西能阻止Swift被设计成这样。其原因很可能是美学,如邓肯C所建议的“有两个参数更有意义”,而有两个参数也更清楚哪些是左操作数,哪些是右操作数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69557225

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档