dpyic24480 2014-09-01 04:31
浏览 33
已采纳

抽象数据类型构造函数可以被不小心绕过吗?

I'm trying to make an abstract data type representing a positive number:

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) {}

Here are some example uses:

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) {}

If you replace m.UsePositiveNum(pn) with m.UsePositiveNum(0), it still compiles, bypassing the positive number typecheck. Why?

  • 写回答

3条回答 默认 最新

  • 普通网友 2014-09-01 06:10
    关注

    What is happening here is that 0 is an untyped constant. Such constants are covered by this 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.

    Since positiveNum's underlying type is int, which can represent 0, the conversion happens without error.

    @peterSO's answer provides a way to avoid this implicit conversion, since there is no implicit conversion from an integer constant to a struct. Note that it won't protect against a malicious user creating a value like positive.Positive{0}, but that is usually not a concern.

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

报告相同问题?

悬赏问题

  • ¥15 vue3加ant-design-vue无法渲染出页面
  • ¥15 matlab(相关搜索:紧聚焦)
  • ¥15 基于51单片机的厨房煤气泄露检测报警系统设计
  • ¥15 路易威登官网 里边的参数逆向
  • ¥15 Arduino无法同时连接多个hx711模块,如何解决?
  • ¥50 需求一个up主付费课程
  • ¥20 模型在y分布之外的数据上预测能力不好如何解决
  • ¥15 processing提取音乐节奏
  • ¥15 gg加速器加速游戏时,提示不是x86架构
  • ¥15 python按要求编写程序