function - Go - void函数和直接赋值

标签 function go void assign

我的 Go 语言有点问题。 我有这个结构:

type Time struct{
    hour,min,sec int
}

还有这个初始化它的函数:

func init_Time(t Time) (int,int,int){
    t.hour, t.min, t.sec = time.Now().Clock()
    return t.hour, t.min, t.sec
}

主要是:

func main(){
   var Tm Time
   Tm.hour, Tm.min, Tm.sec = init_Time(Tm)
   fmt.Printf("Time: %d:%d:%d", Tm.hour, Tm.min, Tm.sec)
} 

我也导入了 time 包。它工作得很好,但我有 2 个问题:

  1. 在我的代码中,为什么在 init_Time 函数中对变量 (hour,min,sec) 赋值两次:

    t.hour, t.min, t.sec = time.Now().Clock()

main() 中:

Tm.hour, Tm.min, Tm.sec = init_Time(Tm)

有必要还是我的错?

  1. 为什么如果我通过将 init_Time 函数转换为 void 函数来修改它,它会返回值 "Time: 0:0:0" 而不是当前时间?

(示例:)

func init_Time(t Time) {
      t.hour, t.min, t.sec = time.Now().Clock()
}
...
func main(){
     var Tm Time
     init_Time(Tm)
     fmt.Printf("Time: %d:%d:%d", Tm.hour, Tm.min, Tm.sec)
} 

最佳答案

调用任何函数(或方法)并传递值都会生成值的副本,并且在函数(或方法)内部您只能修改副本。因此,如果您没有将第一个示例中的返回值分配给 Time 的字段,则当函数返回时,在 init_Time() 中所做的更改将丢失。这也回答了您的第二个问题。

如果您希望调用者观察到变化,您必须将一个指针 传递给您的值,并让函数修改指向 的值。在这种情况下,甚至不需要返回(修改后的)值:

func InitTime(t *Time) {
  t.hour, t.min, t.sec = time.Now().Clock()
}

使用它:

t := Time{}
InitTime(&t)
fmt.Printf("Time: %d:%d:%d\n", t.hour, t.min, t.sec)

输出(在 Go Playground 上尝试):

Time: 23:0:0

(请注意,Go Playground 上的当前时间始终从 23:00:00 开始。)

创建类似函数的“构造函数”也是惯用的:

func NewTime() *Time {
    t := &Time{}
    t.hour, t.min, t.sec = time.Now().Clock()
    return t
}

使用它:

t2 := NewTime()
fmt.Printf("Time: %d:%d:%d\n", t2.hour, t2.min, t2.sec)

输出相同。

查看相关问题:

Golang Operator Overloading

Copy instances of type T, when any of the methods of a named type T have a pointer receiver

关于function - Go - void函数和直接赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44434544/

相关文章:

function - 带循环的 PostgreSQL 函数

go - 无法获取媒体统计信息VLC

sqlite - 在 Go GORM 中显示 Foreign Keys 的 Foreign Keys

go - 是否可以将 Go 与其他语言混合来创建桌面应用程序?

Python 在不干扰脚本的情况下休眠?

function - 确保kotlin方法是静态的,顶级的或带注释的@JvmStatic

python - Python 上的列表索引错误

c - 如何打印树节点 void 指针指向的该结构的成员?

c - 在运行时永久转换 void 指针

java - 错误 : 'void' type not allowed here