我有以下简单的结构类型。
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/