Спецификация Go для объявлений коротких переменных ясна:
объявление коротких переменных может повторно объявить переменные, если они были первоначально объявлены в одном и том же блоке с тем же типом, ипо крайней мере одна из непустых переменных является новой.
Следовательно, в коротком объявлении переменной нельзя повторно объявить переменные, первоначально объявленные в другом блоке.
Вотпример того, как обойти это ограничение, объявив локальную переменную (e
) во внутреннем блоке и присвоив ее (e
) переменной (err2
), объявленной во внешнем блоке.
package main
import (
"fmt"
"os"
)
func f() (err1 os.Error, err2 os.Error) {
fi, err1 := os.Stat("== err1 os.Error ==")
_ = fi
{
fi, e := os.Stat("== e os.Error ==")
_ = fi
err2 = e
}
return
}
func main() {
err1, err2 := f()
fmt.Println("f() err1:", err1)
fmt.Println("f() err2:", err2)
}
Вывод:
f() err1: stat == err1 os.Error ==: no such file or directory
f() err2: stat == e os.Error ==: no such file or directory
Вот предыдущий пример, переписанный для использования явных регулярных объявлений переменных и именованных параметров функции вместо неявных коротких объявлений переменных.Объявления переменных всегда можно записать явно как обычные объявления переменных или именованные параметры функций;неявные короткие объявления переменных являются просто сокращением для объявлений обычных переменных.
package main
import (
"fmt"
"os"
)
func f() (err1 os.Error, err2 os.Error) {
var fi *os.FileInfo
fi, err1 = os.Stat("== err1 os.Error ==")
_ = fi
{
var fi *os.FileInfo
fi, err2 = os.Stat("== err2 os.Error ==")
_ = fi
}
return
}
func main() {
err1, err2 := f()
fmt.Println("f() err1:", err1)
fmt.Println("f() err2:", err2)
}
Вывод:
f() err1: stat == err1 os.Error ==: no such file or directory
f() err2: stat == err2 os.Error ==: no such file or directory
В вашем примере краткое объявление переменной err
повторно объявляет объявление возвращаемого параметраerr
;они находятся в одном блоке.Поэтому новый err
не маскирует возвращаемый параметр err
.