2 回答
TA贡献1865条经验 获得超7个赞
Go做不到这个(我不认为,我不认为几个月让我有经验)
ADA 可以,而 C++ 有时可以但不干净(constexpr 和 static_assert)。
但真正的问题/要点在这里,为什么重要?我使用 Go 和 GCC 作为编译器,GCC 非常聪明,尤其是使用 LTO,恒定传播是最容易应用的优化之一,它不会打扰检查(你是(无论如何我们在 C 中称之为)静态检查初始化 AB 和 C,GCC 对此进行了优化(如果它有函数的定义,则使用 LTO))
现在这有点离题了,所以我将停止使用那个混搭的 blob,但是除非您的程序受 CPU 限制,否则测试一个值的合理性是好的,不要担心。
总是写更容易阅读的东西,你会感谢你以后所做的
因此,请执行您的运行时检查,如果编译器有足够的信息来处理它,如果它可以推断(证明)它们不会抛出,它就不会费心去做,像这样的常量值它会很容易地发现它。
附录
很难进行编译时检查,例如,c++ 中的 constexpr 非常有限(它涉及的所有内容也必须是 constexpr 等)——它不能很好地与普通代码一起使用。
假设一个值来自用户输入?该检查必须在运行时进行,如果您编写了两组约束(但是这行得通),一组用于编译,一组用于运行,那将是愚蠢的(并且违反 DRY)。
我们能做的最好的事情就是让编译器非常聪明,而 GCC 就是这样。我相信其他人也很好(“除了 MS,我从来没有听到过对它的赞美,但作者很聪明,因为他们一开始就编写了一个 C++ 解析器!)
TA贡献1873条经验 获得超9个赞
一种可能适合您需要的略有不同的方法是使函数成为该类型的方法并导出有效值集,但不是构造新值的方法。
例如:
package foo
import (
"fmt"
)
// subset of values
const A = fooVal(0)
const B = fooVal(1)
const C = fooVal(2)
// type that implements the foo_iface interface
type fooVal int
// function that requires A, B or C
func (val fooVal) Bar() {
fmt.Println(val)
}
使用人:
package main
import "test/foo"
func main() {
foo.A.Bar() // OK, prints 0
foo.B.Bar() // OK, prints 1
foo.C.Bar() // OK, prints 2
foo.4.Bar() // syntax error: unexpected literal .4
E := foo.fooVal(5) // cannot refer to unexported name foo.fooVal
}
- 2 回答
- 0 关注
- 219 浏览
添加回答
举报