在swift中使用POP创建一个通用的add函数()
Using POP in swift to create a generic add function ()
更新: 这只是为了学习POP。我知道我们可以使用 <+> 运算符,但我想知道我错过了什么
我正在尝试创建一个 swift 通用函数来添加两个元素:
- 如果元素为数字,则只需添加它们。
- 如果元素是字符串,则连接它们。
这是我的代码:
protocol NumericType {
func +(lhs: Self, rhs: Self) -> Self
}
extension Double : NumericType {}
extension Float : NumericType {}
extension Int : NumericType {}
protocol Addable {
func addGenerically<T>(element1: T, element2: T) -> T
}
extension Addable where Self:NumericType {
func addGenerically<T:NumericType>(element1: T, element2: T) -> T {
return (element1) + (element2)
}
}
// This throws error: inheritance from non protocol, non class type strings
extension Addable where Self:String {
func addGenerically<T:String>(element1: T, element2: T) -> T {
return (element1) + (element2)
}
}
class MyVC: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
let n1 = Double(3.4)
let n2 = Double(3.3)
let n3 = Addable.addGenerically(n1, element2: n2)
}
任何想法如何完成和使用它?
这里的问题几乎就是错误所说的——你不能从非协议或非class类型继承。
String
作为 Swift 中的 struct
实现,结构没有继承。您无法创建 String
的 'sub-struct'。取而代之的是,使用协议来定义通用功能并提供层次感。
因此您需要使用一个协议来限制扩展,就像您对 NumberType
协议所做的一样。例如:
protocol AddableString {
func +(lhs: Self, rhs: Self) -> Self
}
extension String : AddableString {}
extension Addable where Self:AddableString {
func addGenerically<T:AddableString>(element1: T, element2: T) -> T {
return (element1) + (element2)
}
}
然而,这太啰嗦了,我什至不确定你将如何实现这个功能——因为你必须在现有值上使用它,而不是使用那个值在另外。你根本不能像这样使用它:
Addable.addGenerically(n1, element2: n2)
因为 Addable
不是具体类型,所以不能对其调用静态函数。
我建议通过将您的协议合并为一个 Addable
协议来显着简化您的代码。这将允许您定义要添加的类型,以及可以在 addGenerically
函数中使用的类型。例如:
protocol Addable {
func +(lhs: Self, rhs: Self) -> Self
}
extension Double : Addable {}
extension Float : Addable {}
extension Int : Addable {}
extension String : Addable {}
func addGenerically<T:Addable>(lhs:T, rhs:T) -> T {
return lhs + rhs
}
...
let n1 = 3.4
let n2 = 3.3
let n3 = addGenerically(n1, rhs: n2)
虽然我通常不希望用新的全局函数污染全局命名空间——你应该考虑让函数采用单个 Self
参数而不是 Addable
的扩展,允许你通过在另一个 Addable
上调用该方法来使用添加给定的 Addable
(尽管这会删除泛型,您可能不想在演示中使用它):
protocol Addable {
func +(lhs: Self, rhs: Self) -> Self
func addGenericallyWith(rhs: Self) -> Self
}
extension Double : Addable {}
extension Float : Addable {}
extension Int : Addable {}
extension String : Addable {}
extension Addable {
func addGenericallyWith(rhs:Self) -> Self {
return self + rhs
}
}
...
let n1 = 3.4
let n2 = 3.3
let n3 = n1.addGenericallyWith(n2)
尽管请注意,我们在这里所做的只是重新实现 +
运算符! Swift 已经可以根据您使用的类型推断要调用哪个 +
运算符实现 – 因此您不需要创建自己的 addGenerically
函数。
更新: 这只是为了学习POP。我知道我们可以使用 <+> 运算符,但我想知道我错过了什么
我正在尝试创建一个 swift 通用函数来添加两个元素: - 如果元素为数字,则只需添加它们。 - 如果元素是字符串,则连接它们。
这是我的代码:
protocol NumericType {
func +(lhs: Self, rhs: Self) -> Self
}
extension Double : NumericType {}
extension Float : NumericType {}
extension Int : NumericType {}
protocol Addable {
func addGenerically<T>(element1: T, element2: T) -> T
}
extension Addable where Self:NumericType {
func addGenerically<T:NumericType>(element1: T, element2: T) -> T {
return (element1) + (element2)
}
}
// This throws error: inheritance from non protocol, non class type strings
extension Addable where Self:String {
func addGenerically<T:String>(element1: T, element2: T) -> T {
return (element1) + (element2)
}
}
class MyVC: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
let n1 = Double(3.4)
let n2 = Double(3.3)
let n3 = Addable.addGenerically(n1, element2: n2)
}
任何想法如何完成和使用它?
这里的问题几乎就是错误所说的——你不能从非协议或非class类型继承。
String
作为 Swift 中的 struct
实现,结构没有继承。您无法创建 String
的 'sub-struct'。取而代之的是,使用协议来定义通用功能并提供层次感。
因此您需要使用一个协议来限制扩展,就像您对 NumberType
协议所做的一样。例如:
protocol AddableString {
func +(lhs: Self, rhs: Self) -> Self
}
extension String : AddableString {}
extension Addable where Self:AddableString {
func addGenerically<T:AddableString>(element1: T, element2: T) -> T {
return (element1) + (element2)
}
}
然而,这太啰嗦了,我什至不确定你将如何实现这个功能——因为你必须在现有值上使用它,而不是使用那个值在另外。你根本不能像这样使用它:
Addable.addGenerically(n1, element2: n2)
因为 Addable
不是具体类型,所以不能对其调用静态函数。
我建议通过将您的协议合并为一个 Addable
协议来显着简化您的代码。这将允许您定义要添加的类型,以及可以在 addGenerically
函数中使用的类型。例如:
protocol Addable {
func +(lhs: Self, rhs: Self) -> Self
}
extension Double : Addable {}
extension Float : Addable {}
extension Int : Addable {}
extension String : Addable {}
func addGenerically<T:Addable>(lhs:T, rhs:T) -> T {
return lhs + rhs
}
...
let n1 = 3.4
let n2 = 3.3
let n3 = addGenerically(n1, rhs: n2)
虽然我通常不希望用新的全局函数污染全局命名空间——你应该考虑让函数采用单个 Self
参数而不是 Addable
的扩展,允许你通过在另一个 Addable
上调用该方法来使用添加给定的 Addable
(尽管这会删除泛型,您可能不想在演示中使用它):
protocol Addable {
func +(lhs: Self, rhs: Self) -> Self
func addGenericallyWith(rhs: Self) -> Self
}
extension Double : Addable {}
extension Float : Addable {}
extension Int : Addable {}
extension String : Addable {}
extension Addable {
func addGenericallyWith(rhs:Self) -> Self {
return self + rhs
}
}
...
let n1 = 3.4
let n2 = 3.3
let n3 = n1.addGenericallyWith(n2)
尽管请注意,我们在这里所做的只是重新实现 +
运算符! Swift 已经可以根据您使用的类型推断要调用哪个 +
运算符实现 – 因此您不需要创建自己的 addGenerically
函数。