当前位置: 首页 > 面试题库 >

为什么可以键入别名函数并在不进行强制转换的情况下使用它们?

薄欣怿
2023-03-14
问题内容

在Go中,如果您定义新类型,例如:

type MyInt int

然后,您不能将a传递给MyInt需要int的函数,反之亦然:

func test(i MyInt) {
    //do something with i
}

func main() {
    anInt := 0
    test(anInt) //doesn't work, int is not of type MyInt
}

精细。但是,为什么同样的不适用于功能呢?例如:

type MyFunc func(i int)
func (m MyFunc) Run(i int) {
    m(i)
}

func run(f MyFunc, i int) {
    f.Run(i)
}

func main() {
    var newfunc func(int) //explicit declaration
    newfunc = func(i int) {
        fmt.Println(i)
    }
    run(newfunc, 10) //works just fine, even though types seem to differ
}

现在,我没有抱怨,因为它使我不必像在第一个示例中那样必须显式转换newfunc为type
MyFunc。看起来似乎不一致。我敢肯定有充分的理由。谁能启发我?

我问的原因主要是因为我想以这种方式缩短一些较长的函数类型,但是我想确保这样做是可以预期的并且可以接受的:)


问题答案:

事实证明,这是我对Go如何处理类型的一种误解,可以通过阅读规范的相关部分来解决:

http://golang.org/ref/spec#Type_identity

我不知道的相关区别是 命名未命名 类型的区别。

命名 类型是具有名称的类型,例如int,int64,float,string,bool。此外,您使用“ type”创建的任何类型都是命名类型。

未命名的 类型是诸如[] string,map [string] string,[4] int之类的类型。它们没有名称,只是对应于其结构的描述。

如果比较两个命名类型,则名称必须匹配,以便它们可以互换。如果您比较命名类型和未命名类型,则 只要基础表示形式匹配 ,就可以了!

例如,给定以下类型:

type MyInt int
type MyMap map[int]int
type MySlice []int
type MyFunc func(int)

以下是无效的:

var i int = 2
var i2 MyInt = 4
i = i2 //both named (int and MyInt) and names don't match, so invalid

以下很好:

is := make([]int)
m := make(map[int]int)
f := func(i int){}

//OK: comparing named and unnamed type, and underlying representation
//is the same:
func doSlice(input MySlice){...}
doSlice(is)

func doMap(input MyMap){...}
doMap(m)

func doFunc(input MyFunc){...}
doFunc(f)

我有点不知所措,我不早知道,所以我希望可以为其他人澄清一下百灵鸟!而且意味着比我最初想像的要少得多的铸造:)



 类似资料:
  • 我必须写一个方法,它有一个Integer类型的参数,并且必须返回一个Character类型的对象。如果给定参数的值可以表示为字符对象,则将其作为字符返回。否则返回null。 我的任务制定得很糟糕,它说:“不安全的转换(例如从int到char)在你的代码中是不允许的”,我想这不是不安全的,但也不允许? 到目前为止我的代码: 我试图通过任何方式修复它,但就是无法提出不使用不安全转换的解决方案,非常感谢

  • 问题内容: 所以这工作: 但这不是: 总而言之,我得到了第一部分(拳击),但是我发现第二部分不起作用是非常不直观的。是否有特定的原因(除了String从Object继承而int不从Object继承)? 编辑: 为了完善我的问题,这也可以: 但是,以下内容却没有: 令人惊讶的是,您遇到了与String相同的问题: 在最后一行产生类强制转换异常。仍然有效: 问题答案: 我刚刚找到了我正在寻找自己的答案

  • 请问我们在使用类型注释的时候,何时使用type class名,何时使用class名呢? 我经过如下实验: 比如以上,是否是返回类型为class名称的时候,使用 typeof class名,返回类对象的时候,使用class名?

  • 问题内容: 我正在使用Java 1.6.0_25。 我定义了一个注释: 后来当我使用getAnnotation时: 编译器和IDE同意我必须强制转换结果,但是getAnnotation在Java 1.5文档中声明为: 由于Resource.class是Class类型,在我看来,这意味着cls.getAnnotation(Resource.class)应该返回Resource类型,并且我需要进行强制

  • 问题内容: 我在一个新项目中将Swift样板代码用于Core Data。我的文件有一个定义的单一实体()和一个属性()。 我有一个看起来像这样的文件: 当我运行它时,它起作用: 我什至可以进入iOS模拟器正在使用的SQLite数据库,并确认已添加该行。 但是,当我运行与上面完全相同的代码,但使用而不是时,出现了与…行关联的错误消息,导致崩溃。如果我继续执行,则每次执行线程1时它都会到达并位于线程1