Function 声明和定义中的不同函数参数类型

Function 声明和定义中的不同函数参数类型,function,go,types,Function,Go,Types,在标准库中,src/time/sleep.go具有以下功能: // Interface to timers implemented in package runtime. // Must be in sync with ../runtime/runtime.h:/^struct.Timer$ type runtimeTimer struct { i int when int64 period int64 f func(interface{}

在标准库中,
src/time/sleep.go
具有以下功能:

// Interface to timers implemented in package runtime.
// Must be in sync with ../runtime/runtime.h:/^struct.Timer$
type runtimeTimer struct {
    i      int
    when   int64
    period int64
    f      func(interface{}, uintptr) // NOTE: must not be closure
    arg    interface{}
    seq    uintptr
}

func startTimer(*runtimeTimer)
startTimer
的参数类型是
*runtimeTimer
startTimer
实现在
src/runtime/time.go
中,如下所示:

// Package time knows the layout of this structure.
// If this struct changes, adjust ../time/sleep.go:/runtimeTimer.
// For GOOS=nacl, package syscall knows the layout of this structure.
// If this struct changes, adjust ../syscall/net_nacl.go:/runtimeTimer.
type timer struct {
    i int // heap index

    // Timer wakes up at when, and then at when+period, ... (period > 0 only)
    // each time calling f(arg, now) in the timer goroutine, so f must be
    // a well-behaved function and not block.
    when   int64
    period int64
    f      func(interface{}, uintptr)
    arg    interface{}
    seq    uintptr
}

// startTimer adds t to the timer heap.
//go:linkname startTimer time.startTimer
func startTimer(t *timer) {
    if raceenabled {
        racerelease(unsafe.Pointer(t))
    }
    addtimer(t)
}
这里,
startTimer
的参数类型是
*timer

*timer
*runtimeTimer
是不同的类型。因为根据戈朗的说法:

如果两个指针类型具有相同的基类型,则它们是相同的

定义的类型始终不同于任何其他类型

timer
runtimetimetimer
都是定义的类型,因此
*timer
*runtimetimetimer
是不同的类型

根据可分配性,函数调用中参数的分配也不应该起作用

谁能给我解释一下吗

谢谢

//go:linkname
注释是:

//转到:linkname localname importpath.name

//go:linkname指令指示编译器使用“importpath.name”作为源代码中声明为“localname”的变量或函数的对象文件符号名。由于该指令可以破坏类型系统和包模块化,因此仅在导入“不安全”的文件中启用该指令

此指令告诉编译器使用
time.startTimer
作为此函数的目标文件符号


这只是一份声明。在链接时,time.startTimer名称绑定到运行时包中实现的函数。此名称匹配忽略类型安全性和模块性


这些诡计的目的是允许时间包调用运行时包函数,而无需从运行时包导出该函数。

“此名称匹配忽略类型安全性和模块性”,因此只要函数名称相同,我就可以对
time.startTimer
的参数类型使用任何类型。例如,我甚至可以使用它:
func-startTimer()
func-startTimer(int)
,对吗?程序将使用
func-startTimer()
func-startTimer(int)
进行构建,但不能保证程序将在没有segfault的情况下执行调用。
//go:linkname startTimer time.startTimer
func startTimer(t *timer) {
    if raceenabled {
        racerelease(unsafe.Pointer(t))
    }
    addtimer(t)
}