【问题标题】:Extending Array with generic floating point math type使用通用浮点数学类型扩展数组
【发布时间】:2020-07-09 05:22:21
【问题描述】:

我想实现以下但无法修复错误:“非标称类型'元素'不支持显式初始化”

最初的尝试:

public extension Array where Element: FloatingPointMathType {


    func mean<Element>() -> Element  {
        let sum: Element = reduce (0.0, +) as! Element

        return sum / Element(count) // ==> Non-nominal type 'Element' does not support explicit initialization
    }
}

另外,我想知道为什么它需要 as! Element 演员表

作为比较,如下本地函数编译没有问题:

    func mean<Element: FloatingPointMathType>(_ e: [Element]) -> Element  {
        let sum: Element = e.reduce (0.0, +)

        return sum / Element(e.count)
    }

【问题讨论】:

  • FloatingPointMathType 是新协议吗?你的 Swift 版本是什么?请注意,mean&lt;Element: FloatingPointMathType&gt; 在集合扩展中非常具有误导性。您正在创建一个与集合 Element 无关的新泛型类型
  • Swift 5 / Xcode 11.3.1

标签: arrays swift generics


【解决方案1】:

无法准确说出问题所在,因为我们不知道您的FloatingPointMathType 协议是如何定义的。您的实现中存在一些问题(主要是,您不想定义泛型函数mean&lt;Element&gt;;扩展已经在Element 类型上进行了参数化,并且泛型参数引入了一个隐藏它的新类型名称(而且那个新类型是未绑定的,所以你不能用它做任何事情)。

以下内容适用于标准库的FloatingPoint 协议:

public extension Collection where Element: FloatingPoint {
  func mean() -> Element  {
    reduce(into: 0, +=) / Element(count) 
  }
}

【讨论】:

  • 请注意,对于空数组,这将返回 nan
  • 是的,空集合没有明确的统计平均值; nan 在大多数情况下是最明智的结果,但您可能希望检测一个空集合并在某些情况下返回零。或者,您可以返回 Optional 并在集合为空时生成 nil。
  • 感谢@StephenCanon 的回答(虽然我没有得到你对 C++ 的参考)。根据NaN,代码是我实现的精简版本,用于演示我面临的问题。
猜你喜欢
  • 1970-01-01
  • 2021-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多