我正在开始使用Swift。我以前的编程背景主要是Python,因此我倾向于在S​​wift中寻找Python的编码方式,幸运的是它的部分灵感来自Python。在Python中,有一种非常强大的方法可以通过使用特殊方法在类中重载运算符。我知道我们可以通过在某个名称空间中定义一个函数来在Swift中重载运算符,在该空间中我们需要这种特殊行为,但是我还没有找到一种在类上重载运算符的方法。

编辑-添加示例。

class Vector(object):
    def __init__(self, *args):  # Initializing a vector of random size
        self.vector = tuple(args)

    def __len__(self):  # This sources the data to the built-in len() function
        return len(self.vector)

    def __getitem__(self, i):  # Overloads [ ] operator
        return self.vector[i]

    def __add__(self, vector):  # Overloads + operator
        if len(self) != len(vector):
            raise ValueError("Vectors should be of equal length")
        return tuple([self.vector[i] + vector[i] for i in xrange(len(self))])


a, b = Vector(1, 2, 3, 4), Vector(2, 3, 4, 5)  # My modified tuples

print(a + b)  # this operation is affected
print((1, 2, 3, 4) + (2, 3, 4, 5))  # this is not, since these are standard tuples


输出:

(3, 5, 7, 9)
(1, 2, 3, 4, 2, 3, 4, 5)


在这里,我通过定义add方法和通过定义getitem方法的[]重载了+。该类可以从Python的元组类型以及初始化程序中继承[]行为,但为了提供更多细节,我手动进行了所有操作。由于重载被封装在类中,因此它不会影响一般的操作员行为,因为所有类型和类都定义了自己的特殊方法。

最佳答案

几个不同的运算符使用不同的机制来覆盖。 __getitem__的等效项是覆盖subscript要覆盖加号,您需要在全局空间中实现func +,并最终得到:

class Vector<T> {
    let vector : [T]

    init(values:[T]) {
        vector = values
    }

    subscript(index:Int) -> T {
        get {
            return vector[index]
        }
    }

    func len() -> Int {
        return vector.count
    }
}

protocol Addable {
    func +(lhs:Self, rhs:Self) -> Self
}

func + <T:Addable>(left:Vector<T>, right:Vector<T>) -> Vector<T> {
    var result = [T]()

    assert(left.len() == right.len(), "vectors should be of equal length")
    for i in 0 ..< left.len() {
        result.append( left[i] + right[i] )
    }

    return Vector(values: result)
}


请注意,我已将其实现为通用类,因此分散了。您还需要指出与它一起使用的任何数据类型都实现了Addable协议。这很简单:

extension Int : Addable {}


我可能还会指出,Vector类在这里并没有太多好处,而标准数组类和重写运算符无法提供这些好处,它们看起来像:

func + <T:Addable>(left:Array<T>, right:Array<T>) -> Array<T> {
    var result = [T]()

    assert(left.len() == right.len(), "vectors should be of equal length")
    for i in 0 ..< left.len() {
        result.append( left[i] + right[i] )
    }

    return result
}


无论哪种情况,都可以使用内联+运算符轻松地对Array或Vector进行矢量数学运算。

关于python - Swift中类似Python的运算符重载,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28282928/

10-12 17:44
查看更多