duanaozhong0696 2013-01-21 04:04
浏览 47
已采纳

Go(语言)常规数字类型/界面

I'm trying to write a package in Go that computes a equation using a "generic" type. To be specific, I want to implement the runge kutta 5 approximation.

This approximation calculates the value of a (unknown) function y at the point t0 + h using only the value of y at t0, the start time t0, the step width h and a differential equation dgl which is of the form dy/dt = g(t,y) where g is some function.

This approximation behaves exactly the same when working with scalar types as when working with vectors (or even matrices). More generally speaking: It works with everything that can be added/subtracted to a value of the same type and can be scaled by a scalar (for which I use float64)

So I tried to express this as a Go interface:

type Numeric interface {
    Add(rhs Numeric) Numeric
    Sub(rhs Numeric) Numeric
    Mul(rhs float64) Numeric
}

But when I try to "implement" this interface, I ran into troubles because of the parameters type:

type Vec6F struct {
    x, y, z float64
    vx, vy, vz float64
}

func (lhs *Vec6F) Add(rhs *Vec6F) rk5.Numeric {
    result := new(Vec6F)
    result.x = lhs.x + rhs.x
    result.y = lhs.y + rhs.y
    result.z = lhs.z + rhs.z
    result.vx = lhs.vx + rhs.vx
    result.vy = lhs.vy + rhs.vy
    result.vz = lhs.vz + rhs.vz
    return result
}

This gives me the error

cannot use result (type *Vec6F) as type rk5.Numeric in return argument:
        *Vec6F does not implement rk5.Numeric (wrong type for Add method
                have Add(*Vec6F) rk5.Numeric
                want Add(rk5.Numeric) rk5.Numeric

which is, on the one hand absolutely logic to me (because rhs could be another object implementing Numeric)

But on the other hand: How do I express something like that in Go? In C++ I could use operator overloading instead, but thats not possible in go.

  • 写回答

3条回答 默认 最新

  • doucang6914 2013-01-21 07:51
    关注

    In order to be generic your Add method must take a Numeric parameter. The normal way to deal with this is with a type assertion like this (on playground)

    func (lhs *Vec6F) Add(_rhs Numeric) Numeric {
        result := new(Vec6F)
        rhs := _rhs.(*Vec6F) // type assertion - will panic if wrong type passes
        result.x = lhs.x + rhs.x
        result.y = lhs.y + rhs.y
        result.z = lhs.z + rhs.z
        result.vx = lhs.vx + rhs.vx
        result.vy = lhs.vy + rhs.vy
        result.vz = lhs.vz + rhs.vz
        return result
    }
    

    You could also use a type switch if you had different types you wanted to convert between.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 一道python难题
  • ¥15 用matlab 设计一个不动点迭代法求解非线性方程组的代码
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler
  • ¥15 oracle集群安装出bug
  • ¥15 关于#python#的问题:自动化测试
  • ¥20 问题请教!vue项目关于Nginx配置nonce安全策略的问题
  • ¥15 教务系统账号被盗号如何追溯设备
  • ¥20 delta降尺度方法,未来数据怎么降尺度