在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 函数。