加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Swift,数学函数和协议

发布时间:2020-12-14 04:36:28 所属栏目:百科 来源:网络整理
导读:我正在尝试创建2个协议ArithmeticType和MathematicType,它们将用于泛型运算符函数的where子句 protocol ArithmeticType { func +(lhs: Self,rhs: Self) - Self func -(lhs: Self,rhs: Self) - Self func *(lhs: Self,rhs: Self) - Self func /(lhs: Self,rhs
我正在尝试创建2个协议ArithmeticType和MathematicType,它们将用于泛型运算符函数的where子句

protocol ArithmeticType {
    func +(lhs: Self,rhs: Self) -> Self
    func -(lhs: Self,rhs: Self) -> Self
    func *(lhs: Self,rhs: Self) -> Self
    func /(lhs: Self,rhs: Self) -> Self
}

extension Int : ArithmeticType {
}

extension Double : ArithmeticType {
}

extension Float : ArithmeticType {
}

ArithmeticType按预期工作,Int,Float和Double符合它.但是以下失败了

import Darwin

protocol MathematicType {
    func sin(x: Self) -> Self
}

extension Double : MathematicType {
}

extension Float : MathematicType {
}

我在游乐场的控制台输出上读到:

Playground execution failed: <EXPR>:35:1: error: type 'Double' does not conform to protocol 'MathematicType'
extension Double : MathematicType {
^
<EXPR>:32:10: note: protocol requires function 'sin' with type 'Double -> Self'
    func sin(x: Self) -> Self
         ^
<EXPR>:39:1: error: type 'Float' does not conform to protocol 'MathematicType'
extension Float : MathematicType {
^
<EXPR>:32:10: note: protocol requires function 'sin' with type 'Float -> Self'
    func sin(x: Self) -> Self
         ^

我希望数学函数的行为与上面的运算符相似.有什么办法吗?

==编辑:

现在我意识到试图简化我的问题是一个坏主意.上下文是这个类(可选值的向量)

class Vector<T> {

    var data=[T?]()

    init(fromArray: Array<T>) {
        for i in fromArray {
            data.append(i)
        }
    }

    init() {
    }

    init(count: Int){
        for i in 0..<count {
            data.append(nil)
        }
    }

    init(count: Int,repeatedValue: T) {
        for i in 0..<count {
            data.append(repeatedValue)
        }
    }

    func count() -> Int {
        return data.count
    }

    func append(newElement: T?) {
        data.append(newElement)
    }

    subscript(index: Int) -> T? {
        let i = index>0 ? index % count() : -index % count()
        return data[i]
    }
}

在它之外我为操作符定义了一个通用函数

func +<T where T: ArithmeticType>(left: Vector<T>,right: Vector<T>) -> Vector<T> {
    let resultCount = max(left.count(),right.count())
    var result = Vector<T>()
    for i in 0..<resultCount {
        if left[i] != nil && right[i] != nil {
            result.append(left[i]!+right[i]!)
        }
        else {
            result.append(nil)
        }
    }
    return result
}

这是按预期工作的,但是当我试图将一般的sin函数定义为

func sin<T where T : FloatingPointType>(x: Vector<T>) -> Vector<T>{
    var result = Vector<T>()
    for i in 0..<x.count() {
        if let o = x[i] {
            result.append(sin(o))
        }
        else {
            result.append(nil)
        }
    }
    return result
}

我得到“找不到接受提供的参数的罪的重载”

然后我尝试用MathemticType试图模仿我已经为运算符做的事情

(ArithmeticType的灵感来自IntegerAritmeticType源,通过命令点击导入swift找到的比我对我正在做的事情的了解更多)

==更新

如果我只为Double编写一个专门的函数

func sin(x: Vector<Double>) -> Vector<Double>{
    var result = Vector<Double>()
    for i in 0..<x.count() {
        if let o = x[i] {
            result.append(Darwin.sin(o))
        }
        else {
            result.append(nil)
        }
    }
    return result
}

它按预期工作.

所以这个问题可能会成为“我如何将其概括为Double和Float”?

解决方法

编译器错误是因为您将sin()声明为MathematicType协议的方法,然后声明Double实现了MathematicType,但实际上并没有编写sin()方法.

extension Double {
    func sin(x: Double) -> Double {
        return Darwin.sin(x)
    }
}

我认为这不是你想要的,不是吗?你希望能够写下这个:

let myAngle = 3.14159
let sineValue = myAngle.sin()

如果是这种情况,您的协议和扩展将需要如下所示:

protocol MathematicType {
    func sin() -> Self
}

extension Double : MathematicType {
    func sin() -> Double {
        return Darwin.sin(self)
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读