首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
beego
V2EX  ›  Go

问一个 GO 的底层类型问题

  •  
  •   hheedat · 7 天前 · 1033 次点击
    package main
    
    import "fmt"
    
    type I int
    type M map[string]interface{}
    type M2 map[string]interface{}
    
    func main() {
    	var m M = M{"hello": "world"}
    	printM(m) //可以
    
    	var num I = 123
    	printI(num) //不行的
    
    
    	printM2(m) //不行的
    }
    
    func printI(i int) {
    	fmt.Println(i)
    }
    
    func printM(m map[string]interface{}) {
    	fmt.Println(m)
    }
    
    func printM2(m M2) {
    	fmt.Println(m)
    }
    
    

    众所周知, Iint 是两个类型,但是为啥 M 能直接被当做 map[string]interface{} ?

    proxy

    8 回复  |  直到 2018-07-13 18:21:59 +08:00
        1
    iRiven   7 天前 via Android
    golang 类型不能隐式转换
        2
    ferrum   7 天前 via iPhone
    如果用了 vscode-go 插件,或者其他的 IDE,在写代码时就有提示类型不正确吧。
        3
    zhs227   7 天前
    可以使用类型断言,或者是使用别名。 别名的方式是 type I = int, 支持 1.9 以上版本,但有些其它的限制。
        4
    yufpga   7 天前
    I, M, M2,int, map[string]interface{} 确实是五种不同的类型,所以 printI(num), printM2(m) 不能执行是对的,也能够理解。但是 printM(m)为什么可以,说实话,我回答不上来,逻辑上讲不通。只能归结为 golang 中的 map 是一种引用类型,有我们不知道的其他原因。假如楼主尝试一下 go 中的其他引用类型对比 map, 比如
    type C chan int
    func printC(c chan int){}
    也能得到类似 map 的结果, 而我尝试了其他的值类型(包括定义一个 struct), 得到的结果是与 int 这种结果一致的。额外说一下,golang 中只有 map, slice, channel 三种引用累心,其余都是值类型。
        5
    Leigg   7 天前 via iPhone
    @yufpga 引用类型还包括反射,函数,接口
        6
    Lpl   7 天前
    @Leigg 接口不应该叫引用类型,应该叫指针类型
        7
    hheedat   7 天前
    @yufpga 有答案了
    https://golang.org/ref/spec#Assignability
    x's type V and T have identical underlying types and at least one of V or T is not a defined type.
    all numeric types are defined types
        8
    yufpga   7 天前
    @hheedat 谢谢, 明白了. 总结一下: 根据文档描述 The new type is called a defined type. It is different from any other type, including the type it is created from. 那么所有通过 type 定义的结构体 /类型也都是 defined type(当然不全包括 type T1 = T 这种形式定义的部分新类型). 文档上还说 Boolean type, numberic type, string type 都是 defined type.

    那么问题来了,有哪些不是 defined type: map, channel, slice, pointer, 函数类型 ...(欢迎继续补充, 其实这些类型看上去还是挺有规律的)
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   鸣谢   ·   实用小工具   ·   637 人在线   最高记录 3541   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.1 · 16ms · UTC 19:54 · PVG 03:54 · LAX 12:54 · JFK 15:54
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1