Python-类似于 Swift 中的运算符重载
Python-like operator overloading in Swift
我开始使用 Swift。我以前的编程背景主要是 Python,所以我倾向于在 Swift 中搜索 Pythonic 编码方式,幸运的是它部分受到了 Python 的启发。在 Python 中,有一种非常强大的方法可以通过使用特殊方法来重载 class 中的运算符。我知道我们可以通过在特定名称 space 中定义一个函数来重载 Swift 中的运算符,我们想要这种特殊行为,但我还没有找到重载运算符 class-聪明
编辑 - 添加示例。
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 方法重载了 []。 class 可以从 Python 中的元组类型以及初始化器继承 [] 行为,但我全部手动完成以提供更多细节。由于重载被封装在 class 中,它不会影响一般的运算符行为,因为所有类型和 classes 都定义了它们自己的特殊方法。
使用不同机制覆盖的几个不同运算符。 __getitem__
相当于重写subscript
要重写plus,需要在全局space中实现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 class 并没有太多好处,标准数组 class 和重写运算符无法提供,看起来像:
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
}
在任何一种情况下,您都可以使用内联 +
运算符轻松地对数组或向量执行向量数学运算。
我开始使用 Swift。我以前的编程背景主要是 Python,所以我倾向于在 Swift 中搜索 Pythonic 编码方式,幸运的是它部分受到了 Python 的启发。在 Python 中,有一种非常强大的方法可以通过使用特殊方法来重载 class 中的运算符。我知道我们可以通过在特定名称 space 中定义一个函数来重载 Swift 中的运算符,我们想要这种特殊行为,但我还没有找到重载运算符 class-聪明
编辑 - 添加示例。
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 方法重载了 []。 class 可以从 Python 中的元组类型以及初始化器继承 [] 行为,但我全部手动完成以提供更多细节。由于重载被封装在 class 中,它不会影响一般的运算符行为,因为所有类型和 classes 都定义了它们自己的特殊方法。
使用不同机制覆盖的几个不同运算符。 __getitem__
相当于重写subscript
要重写plus,需要在全局space中实现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 class 并没有太多好处,标准数组 class 和重写运算符无法提供,看起来像:
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
}
在任何一种情况下,您都可以使用内联 +
运算符轻松地对数组或向量执行向量数学运算。