go - 抽象数据类型构造函数可能会被意外绕过?

标签 go abstract-data-type

我正在尝试创建一个代表正数的抽象数据类型:

package m

type positiveNum int

func MakePositiveNum(i int) positiveNum {
    if i < 1 { panic("non positive number") }
    return positiveNum(i)
}

// some function that expects a positive number
func UsePositiveNum(s positiveNum) {}

以下是一些示例用途:

package main
import "m"
func main() {
    pn := m.MakePositiveNum(123)
    //i := 1; m.UsePositiveNum(i) // fails as expected because
                                  // int is passed instead of positiveNum
    //useInt(pn) // fails because trying to pass positiveNum instead of int
    //pn = m.positiveNum(0) // fails as expected because the type is private
    m.UsePositiveNum(pn)
}

func UseInt(int) {}

如果将 m.UsePositiveNum(pn) 替换为 m.UsePositiveNum(0),它仍然可以编译,绕过正数类型检查。为什么?

最佳答案

这里发生的事情是 0untyped constantthis rule about assignability 涵盖了此类常量。 :

A value x is assignable to a variable of type T ("x is assignable to T") in any of these cases:

  • ...
  • x is an untyped constant representable by a value of type T.

由于 positiveNum 的基础类型是 int,它可以表示 0,因此转换不会发生错误。

@peterSO 的答案提供了一种避免这种隐式转换的方法,因为没有从整数常量到结构体的隐式转换。请注意,它无法防止恶意用户创建 positive.Positive{0} 之类的值,但这通常不是问题。

关于go - 抽象数据类型构造函数可能会被意外绕过?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25598863/

相关文章:

c# - 继承具有抽象属性的抽象类

java - int、char也是抽象数据类型吗?

golang - gob 编码接口(interface)错误

Go 服务器未正确响应。

json - 在 Go 中聚合 JSON 对象

c - 在 C 中,如果定义了转换/提升规则,是否可以将原语传递给正在寻找用户定义的数据类型作为输入的函数?

c - 节点已插入,但输入的第一个节点已从列表中删除

haskell - 这种抽象数据类型叫什么?

go - 如何在golang中动态运行函数?

具有并发访问的映射