douhuo1738 2015-10-13 20:21
浏览 20
已采纳

如何确保自定义数据结构中的编译时安全

I am writing some data structures to get my feet wet and learn about the Go language and am struggling with Go's lack of generics.

In my implementations I have chosen to force each user to implement an interface so my structures could refer to these objects abstractly but I don't love my solution because this is not verified at compile-time as you will see.

Comparer Interface

Each object that is held in a container must implement a Compare function of the following signature (onerous if all you wanted to hold were raw types)

type Comparer interface {
    Compare(Comparer) int
}

You could then have various elements that implement the interface like float64 or a custom struct:

float64

type number float64

func (n1 number) Compare(comparer Comparer) int {
    n2, _ := comparer.(number)
    if n1 > n2 {
        return 1
    } else if n1 < n2 {
        return -1
    } else {
        return 0
    }
}

Person

type Person struct {
    Age int
}

func (p1 Person) Compare(comparer Comparer) int {
    p2, _ := comparer.(Person)
    if p1.Age > p2.Age {
        return 1
    } else if p1.Age < p2.Age {
        return -1
    } else {
        return 0
    }
}

And now I can compare some of these things:

func main() {
    fmt.Println(number(2).Compare(number(4)))    // -1
    fmt.Println(Person{26}.Compare(Person{28}))  // -1
    fmt.Println(Person{26}.Compare(number(28)))  //  1
}

The problem here is that I should not be able to compare a Person and a number. I realize that I can check the type at runtime but I would like to find either a) a compile-time way to verify the type or b) a different method to implement data structures generically.

Questions

  1. I know that one can do almost everything one might need with the built in data structures ... but how would someone make their own data structures without generics or runtime type checking?
  2. Since interface implementation in Go appears to use duck typing, how does Go enforce types at compile time?
  • 写回答

1条回答 默认 最新

  • duanlu0559 2015-10-13 20:34
    关注

    I mean there's nothing unsafe about that code... There just isn't compile time safety. For example, in your method below, the first line does a type assertion on comparer, if it's not a number and you didn't have _ for the second item on the LHS then it would return an error and you could act accordingly. Or you could call it without that at all and a panic will occur leaving it up to the caller to handle it (would be appropriate since they're the person calling the method with wrong arguments, would be like getting an InvalidOperationException in C#).

    func (n1 number) Compare(comparer Comparer) int {
        n2, _ := comparer.(number)
        if n1 > n2 {
            return 1
        } else if n1 < n2 {
            return -1
        } else {
            return 0
        }
    }
    

    The difference between this and a language like C# is purely in generics, which allow you to do these kinds of things with more compile time safety (because you're not able to call the method incorrectly). That being said, there was a time before C# had generics and many languages before that which didn't feature them at all. These operations are no more unsafe than the casts you do routinely even in languages that do have generics.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?