douya6229 2017-07-20 20:24
浏览 37
已采纳

覆盖接口指针值

I made an interface meant to do basic math with struct values. The interface's math functions always update the values of the struct's pointer.

My problem is that at some point, I want to overwrite the value to the initial value but I only have the interface to work with. Because it is a pointer interface (not 100% sure if this is what people call it), I am unable to "clone" the initial value of the struct in order to overwrite later.

Please also note I'm trying my best to avoid reflection.

Here is my code. Will probably make a lot more sense than me trying to explain it:

package main

import (
    "fmt"
)

type mather interface {
    add(mather) mather
    sub(mather) mather
}

type float struct {
    value float64
}

func (f *float) add(m mather) mather {
    f.value += m.(*float).value
    return f
}

func (f *float) sub(m mather) mather {
    f.value -= m.(*float).value
    return f
}

func (f *float) get() interface{} {
    return *f
}

func main() {
    var a, b, c mather

    a = &float{2} // this could be any time. approximitly 10 possible types
    b = &float{7} // this could be any time. approximitly 10 possible types

    // float can't be used again below, only mather

    c = a

    fmt.Println(a)
    fmt.Println(b)
    fmt.Println()

    // a's math
    doMath(a)

    // now math is done, we need to reset the value from before the math was done
    // set *a equal to *c. (a == &float{2})
    resetMath(a, c)

    // b's math
    doMath(b)

    // now math is done, we need to reset the value from before the math was done
    // set *b equal to *c. (b == &float{7})
    resetMath(b, c)

    fmt.Println(a)
    fmt.Println(b)

}

func doMath(m mather) {
    m.add(&float{3})
}

func resetMath(m mather, r mather) {
    m = r
}

https://play.golang.org/p/3Szk8uQGy5

  • 写回答

2条回答 默认 最新

  • douzhuanqian8244 2017-07-21 09:49
    关注

    You need to define clone and set method in mather interface, i.e.:

    type mather interface {
        add(mather) mather
        sub(mather) mather
        get() interface{}
        clone() mather
        set(v mather)
    }
    

    The implementation of get, set and clone in float type looks like:

    func (f *float) get() interface{} {
        return f.value
    }
    
    func (f *float) clone() mather {
        return &float{f.value}
    }
    
    func (f *float) set(v mather) {
        switch v := v.(type) {
        case *float:
            f.value = v.value
        //handle other possible types...
        default:
            //handle unknown types
        }
    }
    

    See working example in Playground. The only complicated parts is set in which you should determined the underlying type. Here you can use type switch to get underlying type, then assign it to float. Similar codes need to be added in the other underlying types (you mention that there are 10 possible types).

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

报告相同问题?

悬赏问题

  • ¥20 win11修改中文用户名路径
  • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入
  • ¥15 用土力学知识进行土坡稳定性分析与挡土墙设计
  • ¥70 PlayWright在Java上连接CDP关联本地Chrome启动失败,貌似是Windows端口转发问题
  • ¥15 帮我写一个c++工程
  • ¥30 Eclipse官网打不开,官网首页进不去,显示无法访问此页面,求解决方法
  • ¥15 关于smbclient 库的使用
  • ¥15 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害