Почему явное разыменование необходимо для непосредственного вызова функции, а не для вызова свойства метода - PullRequest
0 голосов
/ 05 апреля 2020

У меня есть этот элегантный код, к которому я довольно серьезно отношусь:

package main

import "fmt"


type CBContainer struct {
    cb func(string)
}

func run1(cb *func(v string)) {
    cb("here")
}

func run2(v *CBContainer) {
    v.cb("here")
}


func main() {

    var cb = func(v string) {
      fmt.Println("resolved data:", v)
    }

    run1(&cb)

    run2(new(CBContainer))

    var v = new(CBContainer)
    v.cb = func(s string) {

    }

    run2(v)

}

У меня два вопроса:

  1. Почему указатель на значение структуры можно назвать, но не указателем на прикол c? Вот так:
func run1(cb *func(v string)) {
  cb("here")  // this won't compile, it says:  Cannot call non-function cb (type *func(v string)) 
}

func run2(v *CBContainer) {
  v.cb("here") // but this is fine
}

другими словами, это будет работать :

func run1(cb *func(v string)) {
  (*cb)("here")   // use the * to deref the func
} 

func run2(v *CBContainer) {
  (*v).cb("here")  // we can explicitly deref the v value, but we aren't required to? why??
}
Второй вопрос, когда я задаю:
  run2(new(CBContainer))

Каково нулевое значение свойства cb fun c в структуре CBContainer? кажется странным Если я вызываю это, я получаю эту ошибку:

pani c: ошибка времени выполнения: неверный адрес памяти или разыменование нулевого указателя

...