【问题标题】:Integer conversion to generic type for calculating average. Non-nominal type does not support explicit initialization整数转换为通用类型以计算平均值。非标称类型不支持显式初始化
【发布时间】:2018-01-01 06:50:36
【问题描述】:

我正在尝试创建一个具有平均功能的通用 Queue 类,但是我在这样做时遇到了麻烦,因为我需要一个协议以某种方式表明 T(Int) 是一个有效的操作。

这是我的尝试

class Queue<T:Numeric & Comparable> {
    private var array:[T]
    .....
    func average() -> T {
        return sum() / T(array.count)
    }
}

但是由于明显的原因,编译器说我不能这样做,因为 T 不支持显式初始化。实现此行为的协议的名称是什么,或者我如何编写自己的代码?

【问题讨论】:

  • 你不会真的想要这个,因为结果总是一个整数
  • 您希望在队列中存储哪些类型?只有整数?还是浮点数?
  • 那么为什么需要基于array.count创建T呢?这对我来说没有意义。您希望除法转换为 T 类型吗?怎么可能?例如,除法的结果如何总是整数?为什么你需要平均值才能成为 T?如果average() 总是返回浮点数还不够吗?
  • @FyodorVolchyok T 完全有可能是支持从Int (array.count) 初始化的类型。可以编写代码以始终返回 Int 平均值,尽管这会导致截断
  • @Alexander 我知道可以编写此代码。但这并不能使它更明智。而且我不明白您需要对某些 ​​generic 数值数组进行四舍五入(以哪种方式?)平均值的情况。或者这种舍入应该在文档中明确定义或从方法名称中明显定义(例如)。

标签: swift


【解决方案1】:

请注意,Numeric 协议还包括FloatingPoint 类型,因此您应该将Queue 泛型类型限制为BinaryInteger。关于您的平均返回类型,您应该返回 Double 而不是通用整数。您的 Queue 类应如下所示:

class Queue<T: BinaryInteger & Comparable> {
    private var array: [T] = []
    init(array: [T]) {
        self.array = array
    }
    func sum() -> T {
        return array.reduce(0, +)
    }
    func average() -> Double {
        return array.isEmpty ? 0 : Double(Int(sum())) / Double(array.count)
    }

    // If you would like your average to return the generic type instead of Double you can use numericCast method which traps on overflow and converts a value when the destination type can be inferred from the context.
    // func average() -> T {
    //     return sum() / numericCast(array.count)
    // }

}

游乐场测试

let queue = Queue(array: [1,2,3,4,5])
queue.sum()       // 15
queue.average()   // 3

如果您想扩展NumericBinaryIntegerFloatingPoint 类型的数组,您可以查看answer

【讨论】:

  • 你的答案假设了太多东西。如果作者需要在队列中存储浮点数怎么办?
  • 标题说整数转换
  • 很公平,我认为它只是错误的通用名称
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多