generics - Swift 泛型运算符

标签 generics swift operator-overloading

我写了这样一个类:

struct Size {
    var width:Double=0
    var height:Double=0
    init(width:Double=0,height:Double=0)
    {
        self.width=width
        self.height=height
    }
    [...]
}

现在我想要将 Size 划分为某个数字的能力,并且我想使用泛型来获取可转换为 Double 的每种类型的函数。例如IntCGFloatFloat

但是当我插入函数时:

func /<T>(lhs:Size,rhs:T)->Size
{
    return Size(width:lhs.width/Double(rhs),height:lhs.height/Double(rhs))
}

我得到了错误

error: cannot invoke 'init' with an argument list of type '(width: Double, height: Double)'
        return Size(width:Double(lhs.width/rhs),height:Double(lhs.height/rhs))
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

这真的很奇怪,因为传递的列表是类中定义的确切类型 (Double)..

如果我这样重写它:

func /<T>(lhs:Size,rhs:T)->Size
{
    let drhs=Double(rhs)
    return Size(width:lhs.width/drhs,height:lhs.height/drhs)
}

然后我得到错误:

error: cannot invoke 'init' with an argument of type 'T'
    let drhs=Double(rhs)
             ^~~~~~~~~~~

这更奇怪,因为 Swift 库文件有很多 Double、Int 或 Float 类型的初始化器:

extension Double {
    init(_ v: UInt8)
    init(_ v: Int8)
    init(_ v: UInt16)
    init(_ v: Int16)
    init(_ v: UInt32)
    init(_ v: Int32)
    init(_ v: UInt64)
    init(_ v: Int64)
    init(_ v: UInt)
    init(_ v: Int)
}

extension Double {
    init(_ v: Float)
    init(_ v: Float80)
}

我的代码有什么问题?

最佳答案

在 swift 中,泛型需要类型安全,这是通过协议(protocol)对其进行约束来实现的。这比在 C++ 中要好得多,在 C++ 中不能假设泛型是安全的。通常,您可以使用标准库中的协议(protocol)来实现这些泛型,但不幸的是,在您的情况下,您需要定义一个特殊的协议(protocol)并扩展您希望能够使用的所有类型。我已经为 Int 和 Float 做了这件事,但你可以对你想使用的所有类型做同样的事情。

protocol DoubleConvertible
{
    func toDouble() -> Double
}
extension Int : DoubleConvertible
{
    func toDouble() -> Double
    {
        return Double(self)
    }
}
extension Float: DoubleConvertible
{
    func toDouble() -> Double
    {
        return Double(self)
    }
}
func /<T : DoubleConvertible>(lhs: Size, rhs: T) -> Size
{
    return Size(width: lhs.width / rhs.toDouble(), height: lhs.height / rhs.toDouble())
}

您必须手动执行此操作的原因是因为没有任何标准库协议(protocol)(据我所知)定义了数字可以转换为 Double 的要求。

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

相关文章:

ios - UITableViewCell 基于百分比的高度和最小高度

python - 是否可以在 Python 中重载逻辑和?

c# - 通用可空枚举

c# - 为什么 IEnumerable<T> 在 C# 4 中是协变的?

Java - 编译器错误 - 类中定义的枚举不能用于同一类中的泛型替换

ios - 隐藏该单元格中的标签后,如何缩小表格 View 中行的大小?

ios - 动态高度 UITableViewCell 内的动态高度 UICollectionView

c++ - 友元和运营商=重载

java - 如何在 Java 中实现成员明智比较?

swift - 无法初始化嵌套泛型