При определении внутренней функции, которая использует переменные внешней области видимости, я должен передать переменные внутренней функции как параметры?
Это зависит от того, чего вы хотите достичь.
То, что вы называете «функцией внутри функции», на самом деле называется «замыканием» (а некоторые люди называют это «лямбда»).
Замыкания захватывают переменные из внешней лексической области видимости, на которые есть ссылки в ее теле. В Go этот захват выполняется «по ссылке» или «по имени», что в основном означает, что каждый раз, когда вызывается замыкание, он «видит» current значения переменных, которые он закрывает, а не значения этих переменных в момент создания закрытия - обратите внимание, что программа:
package main
import (
"fmt"
)
func main() {
i := 42
fn := func() {
fmt.Println(i)
}
fn()
i = 12
fn()
}
выдаст
42
12
И наоборот, когда вы передаете значения в качестве аргументов для вызовов к замыканию, каждый вызов будет видеть именно те значения, которые ему переданы.
Надеюсь, теперь вы понимаете, что стратегия выбора во многом зависит от того, что вы хотите.
Концептуально вы можете рассматривать замыкание как экземпляр специального анонимного типа данных struct
, поля которого являются указателями на переменные, над которыми замыкается замыкание, и каждый вызов этого замыкания аналогичен вызов некоторого (анонимного, единственного) метода, предоставленного этим типом (на самом деле это то, что компилятор обычно делает за вашей спиной, чтобы реализовать замыкание).
Такой «метод» может иметь аргументы, и должен ли он иметь их, и что должно идти в поля типа, и какими должны быть аргументы этого метода, можно судить, используя обычный подход, который вы используете с обычными типами.