generics - Swift 泛型 *= 运算符错误

标签 generics swift

我有以下简单的结构类型。

import Foundation
import SceneKit

protocol Named {
    class var name: String { get }
}

extension Float: Named {
    static var name: String { return "Float" }
}

struct Vector3<T: protocol<Named, FloatingPointType>>: Printable { // This protocol solves the generics issue
    // Properties
    var x, y, z: T
    var description: String {
        return "Vector3<\(T.name)>(\(x), \(y), \(z))"
    }
    // Methods - mutating
    mutating func factored(factor: T) {
        x *= factor
    }

}

我希望能够将创建结构时使用的相同类型作为factored的参数。但这会导致 Cannot invoke *= with an argument list of type (T, T)

我是否需要实现 *= 运算符以及我最终需要的任何其他运算符?我该怎么做?

编辑

在 @matt 建议将 Vector3 声明为遵守 FloatingPointType 协议(protocol)后,它解决了问题。虽然现在我在 factored 方法中得到了 T is not equal to UInt8

最佳答案

更新答案

根据 @matt 的建议,组合协议(protocol)可能在这里最有意义:

protocol NamedAndMultipliable {
    class var name: String { get }
    func *=(inout lhs: Self, rhs: Self)
}

func *=(inout lhs: Int, rhs: Int) {
    lhs = lhs * rhs
}

extension Int : NamedAndMultipliable {
    static var name: String { return "Int" }
}
extension Double : NamedAndMultipliable {
    static var name: String { return "Double" }
}
extension Float : NamedAndMultipliable {
    static var name: String { return "Float" }
}

struct Vector3<T: NamedAndMultipliable>: Printable {
    // Properties
    var x, y, z: T
    var description: String {
        return "Vector3<\(T.name)>(\(x), \(y), \(z))"
    }
    // Methods - mutating
    mutating func factored(factor: T) {
        x *= factor
    }   
}

原始答案

通过执行以下操作,我能够得到我认为您想要的结果:

protocol Named {
    class var name: String { get }
}

protocol Multipliable {
    func *(lhs: Self, rhs: Self) -> Self
}

extension Int : Multipliable {}
extension Double : Multipliable {}
extension Float : Multipliable {}

extension Int : Named {
    static var name: String { return "Int" }
}
extension Double : Named {
    static var name: String { return "Double" }
}
extension Float : Named {
    static var name: String { return "Float" }
}

struct Vector3<T: protocol<Named, Multipliable>>: Printable {
    // Properties
    var x, y, z: T
    var description: String {
        return "Vector3<\(T.name)>(\(x), \(y), \(z))"
    }
    // Methods - mutating
    mutating func factored(factor: T) {
        x = x * factor
    }

}

如果您更喜欢使用 *= 运算符,则可以这样做,但如果您还想支持 Int,则需要添加其功能。

protocol MultipliableIntoSelf {
    func *=(inout lhs: Self, rhs: Self)
}

func *=(inout lhs: Int, rhs: Int) {
    lhs = lhs * rhs
}

extension Int : MultipliableIntoSelf {}
extension Double : MultipliableIntoSelf {}
extension Float : MultipliableIntoSelf {}

protocol Named {
    class var name: String { get }
}

extension Int : Named {
    static var name: String { return "Int" }
}
extension Double : Named {
    static var name: String { return "Double" }
}
extension Float : Named {
    static var name: String { return "Float" }
}

struct Vector3<T: protocol<Named, MultipliableIntoSelf>>: Printable {
    // Properties
    var x, y, z: T
    var description: String {
        return "Vector3<\(T.name)>(\(x), \(y), \(z))"
    }
    // Methods - mutating
    mutating func factored(factor: T) {
        x *= factor
    }

}

关于generics - Swift 泛型 *= 运算符错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27954877/

相关文章:

ios - 停止呈现 PushNotification

ios - 我们可以在不设置 "occupantIDs” 的情况下创建 1-1 chatDialog 吗? (快布乐)

iOS swift NumberFormatter 小数样式本地化

linq - 使用 LINQ 在一行中对一维实例数组应用操作

java - Java中根据子类Type定义父类方法的泛型Type

java - 如何将泛型类参数限制为某些类

java - 类型参数 G 隐藏了类型 G

swift - 在 Swift 字典中存储 Encodable

swift - iOS : GMSPlacePickerViewController Country Restriction

ios - 我在 UICollectionViewCell 中有复选框图像,我想将其显示为选中或未选中?