Реализация стека на Golang
Пытаюсь реализовать простейший стек вызовов на Golang. В качестве образца взял код из книги "Грокаем Алгоритмы", код написан на втором Пайтоне.
def greet(name):
print "hello, " + name + "!"
greet2(name)
print "getting ready to say bye..."
bye()
def greet2(name):
print "how are you, " + name + "?"
def bye():
print "ok bye!"
Вот моя попытка реализации на Го. Проблема состоит в том, что я не могу понять почему я не могу вложить функцию bye() внутри функции greet2 и вызвать в функции greet. Про скоуп уже прочитал, но вменяемых примеров там не было. Так что если вы сможете показать, как мне исправить этот код, я буду вам очень благодарен.
package main
import "fmt"
func greet(name string) string {
fmt.Printf("hello, %v !\n", name)
greet2(name)
fmt.Printf("getting ready to say bye...\n")
bye() // тут проблема
return name
}
func greet2(name string) (func(), string) {
fmt.Printf("how are you, %v ?\n", name)
bye := func() { // и тут
fmt.Println("ok bye!")
}
return bye(), name
}
func main() {
greet("Sasha")
greet2("Sasha")
}
Ответы (2 шт):
У вас есть несколько ошибок. В одном случае Вы возвращаете не функцию, а её значение. В другом случае, функция bye() ещё не определена. playground.
package main
import "fmt"
func greet(name string) string {
fmt.Printf("hello, %v !\n", name)
greet2(name)
fmt.Printf("getting ready to say bye...\n")
// Здесь функция bye не определена, поэтому её и вызвать нельзя
// bye() // тут проблема
return name
}
func greet2(name string) (func(), string) {
fmt.Printf("how are you, %v ?\n", name)
bye := func() { // и тут
fmt.Println("ok bye!")
}
// Здесь Вы пытаетесь вернуть результат, который выдаёт функция bye()
// Нужно же возвращать саму функцию
// return bye(), name
return bye, name
}
func main() {
greet("Sasha")
greet2("Sasha")
}
Функция bye() на питоне не вложенная, в книге просто поехало форматирование (а для питона это катастрофа!). В python (да и не только) нельзя просто так взять и вызвать вложенную функцию из другой функции. Будет рантайм ошибка: NameError: global name 'bar' is not defined в том месте, где вы её попробуете вызвать.
На самом деле, код должен выглядеть вот так:
def greet(name):
print "hello, " + name + "!"
greet2(name)
print "getting ready to say bye..."
bye()
def greet2(name):
print "how are you, " + name + "?"
def bye():
print "ok bye!"
И уж его-то переписать на go, я думаю, у вас не составит абсолютно никакого труда.
Если вы всё же хотите пример со вложенной функцией и её возвратом, то вот как оно должно быть:
package main
import "fmt"
func greet(name string) {
fmt.Printf("hello, %v !\n", name)
bye := greet2(name) // функция greet2 вернула функцию
fmt.Printf("getting ready to say bye...\n")
bye() // тут мы вызвали эту функцию
}
func greet2(name string) func() {
fmt.Printf("how are you, %v ?\n", name)
bye := func() { // тут мы создали анонимную функцию и присвоили её переменной
fmt.Println("ok bye!")
}
return bye // тут мы просто возвращаем переменную
}
func main() {
greet("Sasha")
}