首页 > 解决方案 > 使用地图、切片或通道类型进行类型安全

问题描述

我想知道为什么这段代码在 go 中编译。我预计会出现编译器错误,例如字符串:

package main

import (
    "fmt"
)

type myMap map[string]int
type mySlice []int
type myChan chan int

type myString string

func main() {
    var mm myMap
    var m map[string]int
    m = mm // fine, but expected compiler error

    var ms mySlice
    var s []int
    s = ms // same with slices

    var mc myChan
    var c chan int
    c = mc // or channels

    var mstr myString
    var str string
//  str = mstr // error, as expected
    fmt.Printf("%T %T %T %T %T %T %T %T\n", mm, m, ms, s, mc, c, mstr, str)
}

Playground
为什么我没有得到与那些特殊的“引用类型”映射、切片和chan 的类型不匹配错误?

标签: gotype-safety

解决方案


在前两种情况下不会出现编译时错误,因为语言规范允许这些分配。

规格:作业:

在赋值中,每个值都必须可以分配给它所分配的操作数的类型......

规格:可分配性:

如果以下条件之一适用,则值x分配给类型的变量T(“x可分配给”):T

  • x的类型与 相同T
  • x的类型V,并且T具有相同的基础类型,并且至少有一个VT不是定义的类型。
  • T是一个接口类型并x 实现 T.
  • x是双向通道值,T是通道类型,x的类型VT具有相同的元素类型,并且至少有一个VT不是定义的类型。
  • x是预先声明的标识符nilT是指针、函数、切片、映射、通道或接口类型。
  • x是一个无类型的常量 ,可由 type 的值表示T

强调的规则适用于您的前 2 个案例。但是,它不适用于您的最后一种情况,因为stringmyString都是已定义的类型。没有任何规则适用于您的最后一个案例。


推荐阅读