英文:
Go type automatically converting when it seems like it shouldn't
问题
抱歉,我只能为您提供翻译服务,无法执行代码。以下是您提供的内容的翻译:
对不起,标题可能有些模糊。当我创建一个新类型和一个接受该类型参数的函数时,我没有得到编译错误,但我认为应该会出错。
示例代码:
package search
// 一些随机类型别名
type Search string
// 接受一个字符串并返回 Search 类型
func NewSearch(s string) Search {
return Search(s)
}
// 这里出现了一些奇怪的情况
// 为了进行任意测试,返回一个整数
func PrintSearch(s Search) int {
return 5
}
我的假设是,如果我使用 NewSearch
创建一个对象,我应该能够将其传递给 PrintSearch
并且一切都按预期运行,但如果我将一个原始字符串传递给 PrintSearch
,它不应该编译通过。但是,我没有遇到这种行为。
主要代码:
package main
import (
"fmt"
".../search" // 这里不需要输入完整的路径
)
func main() {
SearchTerm := search.NewSearch("Test")
StringTerm := "Another test"
fmt.Println(search.PrintSearch(SearchTerm)) // 这应该打印出 5
fmt.Println(search.PrintSearch(StringTerm)) // 这应该引发编译错误,但实际上没有
}
似乎如果我将类型和函数写在与 main
相同的包中,一切都按照我预期的方式工作?也就是说,它会引发编译错误。我是否忽略了有关跨包类型转换的某些内容?
英文:
Sorry for the ambiguous title. I'm not getting a compiler error when I believe that I should, based on creating a new type and a function that takes an argument of that type.
The example:
package search
//Some random type alias
type Search string
//Takes a string and returns Search
func NewSearch(s string) Search {
return Search(s)
}
//This is where things are getting weird
//Returns an int just for arbitrary testing
func PrintSearch(s Search) int{
return 5
}
Now my assumption would be, if I created an object using NewSearch
, I would be able to pass it to PrintSearch and have everything run as expected, but if I passed PrintSearch a primitive string, it should not compile. I am not experiencing this behavior.
The main code:
package main
import (
"fmt"
".../search" //no need to type the whole path here
)
func main() {
SearchTerm := search.NewSearch("Test")
StringTerm := "Another test"
fmt.Println(search.PrintSearch(SearchTerm)) // This should print 5
fmt.Println(search.PrintSearch(StringTerm)) // This should throw a compiler error, but it is not
}
It seems like if I write the type and the function in the same package as main, everything works as I'd expect? As in, it throws a compiler error. Is there something I've missed about cross-package type coercion?
答案1
得分: 1
我们可以进一步简化这个例子(playground):
package main
type Foo string
type Bar int
func main() {
var f Foo = "foo"
var b Bar = 1
println(f, b)
}
这在规范的可赋值性部分中有解释。
值x在以下任何情况下都可以赋值给类型为T的变量("x可以赋值给T"):
- x的类型与T相同。
- x的类型V和T具有相同的基础类型,并且V或T中至少有一个不是命名类型。
- T是接口类型,并且x实现了T。
- x是双向通道值,T是通道类型,x的类型V和T具有相同的元素类型,并且V或T中至少有一个不是命名类型。
- x是预声明的标识符nil,T是指针、函数、切片、映射、通道或接口类型。
- x是可由类型T的值表示的无类型常量。
英文:
We can simplify this example a bit further (playground):
package main
type Foo string
type Bar int
func main() {
var f Foo = "foo"
var b Bar = 1
println(f, b)
}
This is explained in the spec's assignability section.
> A value x is assignable to a variable of type T ("x is assignable to
> T") in any of these cases:
>
> * x's type is identical to T.
> * x's type V and T have identical underlying types and at least one of V or T is not a named type.
> * T is an interface type and x implements T.
> * x is a bidirectional channel value, T is a channel type, x's type V and T have identical element types, and at least one of V or T is not a named type.
> * x is the predeclared identifier nil and T is a pointer, function, slice, map, channel, or interface type.
> * x is an untyped constant representable by a value of type T.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论