Próbowałem znaleźć dokładne wyjaśnienie tego, co init()
funkcja robi w Go. Przeczytałem, co mówi Effective Go , ale nie byłem pewien, czy w pełni zrozumiałem, co powiedział. Dokładne zdanie, którego nie jestem pewien, jest następujące:
I wreszcie oznacza w końcu: init jest wywoływany po tym, jak wszystkie deklaracje zmiennych w pakiecie dokonały oceny swoich inicjatorów, a te są oceniane dopiero po zainicjowaniu wszystkich importowanych pakietów.
Co all the variable declarations in the package have evaluated their initializers
znaczy Czy to oznacza, że jeśli zadeklarujesz zmienne „globalne” w pakiecie i jego plikach, init () nie uruchomi się, dopóki wszystkie nie zostaną ocenione, a następnie uruchomi całą funkcję init, a następnie main () po uruchomieniu ./main_file_name?
Przeczytałem również książkę Go Marka Summerfielda:
Jeśli pakiet ma jedną lub więcej funkcji init (), są one automatycznie wykonywane przed wywołaniem funkcji main () pakietu głównego.
W moim rozumieniu init()
ma to znaczenie tylko wtedy, gdy uruchamiasz zamierzasz uruchomić main (), prawda? lub pakiet główny. Każdy rozumie bardziej precyzyjnie init()
, popraw mnie
init()
myślę, że jest to kwestia pojedynczego pakietu ... Czy to oznacza, że jeśli różne pliki mają swoje własneinits
, wszystkie ininty są zawsze uruchamiane tuż przed uruchomieniem main ()? Czy możesz również wyjaśnić mi jedną rzecz, dlaczego miałbyś init () bez głównego i jak to działa? Czy to znaczy, że init () jest ostatnią rzeczą uruchomioną przed zaimportowaniem pakietu? W przeciwnym razie, jeśli nie zostanie zaimportowany i nie ma głównego, program nigdy się nie uruchomi ... prawda? (chyba że to plik testowy ...)main
, na przykład, jeśli trzeba zainicjować kilka zmiennych lub załadować niektóre pliki lub wykonać jednorazowe obliczenia. teraz, jeśli cały program jest jednym pakietem, który tak naprawdę nie jest potrzebny, jednak jeśli jest to wiele pakietów, niektóre z nich mogą wymagać specjalnej inicjalizacji.init
jest architektura wtykowa, jak w przypadku dowódcy Cobry . Zwróć uwagę, jakinit
w przykładach jest to wspomnianeZobacz to zdjęcie. :)
import --> const --> var --> init()
Jeśli pakiet importuje inne pakiety, importowane pakiety są najpierw inicjowane.
Stała inicjalizacja stałej bieżącego pakietu.
Następnie inicjowane są zmienne bieżącego pakietu.
Na koniec
init()
wywoływana jest funkcja bieżącego pakietu.źródło
Coś do dodania do tego (co dodałbym jako komentarz, ale czas pisania tego postu nie miałbym jeszcze wystarczającej reputacji)
Mając wiele inits w tym samym pakiecie, nie znalazłem jeszcze żadnego gwarantowanego sposobu, aby wiedzieć, w jakiej kolejności będą one uruchamiane. Na przykład mam:
Oba
config.go
irouter.go
zawierająinit()
funkcje, ale gdy uruchomiona zostałarouter.go
funkcja uruchomiona jako pierwsza (co spowodowało panikę w mojej aplikacji).Jeśli masz wiele plików, każdy z własną
init()
funkcją jest bardzo świadomy, że nie masz gwarancji, że dostaniesz jeden przed drugim. Lepiej jest użyć zmiennego przypisania, jak pokazuje OneToOne w swoim przykładzie. Najlepsze jest to, że ta deklaracja zmiennej nastąpi przed WSZYSTKIMIinit()
funkcjami pakietu.Na przykład
config.go:
router.go:
niezależnie od tego
var ConfigSuccess = configureApplication()
, czy istnieje wrouter.go
lubconfig.go
, zostanie uruchomiony przed uruchomieniem EITHERinit()
.źródło
func initialize|loadConfig|connect
oddzielony odfunc init
, pozostawiając func init () dla podstawowych rzeczy (bez paniki). Ta separacja eliminuje również potrzebę włamania do zapewnienia kolejności inicjowania. Mam nadzieję, że będę pomocny.init()
wywołań w ramach jednego pakietu jest podyktowana sposobem, w jaki są one podawane do kompilatora; tego
rozkazy narzędziowe pliki alfabetycznie. Odtąd w jednym pliku są one inicjowane w kolejności składniowej. edytowane do wyboru słowaOto inny przykład - https://github.com/alok87/gobyexample/blob/master/init/init.go
Wyjście powyższego programu
źródło
Weźmy na przykład framework lub bibliotekę, którą projektujesz dla innych użytkowników, ci użytkownicy ostatecznie będą mieli
main function
kod w celu uruchomienia swojej aplikacji. Jeśli użytkownik zaimportuje bezpośrednio paczkę projektu biblioteki, wówczas teninit
paczka zostanie wywołana ( raz ) przede wszystkim. To samo dotyczy pakietu głównego biblioteki itp.Wiele razy możesz chcieć wykonać blok kodu bez istnienia
main func
, bezpośrednio lub nie.Jeśli jako twórca wyimaginowanej biblioteki zaimportujesz pod-pakiet biblioteki, który ma
init
funkcję, zostanie ona wywołana jako pierwsza, a raz nie będziesz mieć,main func
ale musisz się upewnić, że niektóre zmienne lub tabela, zostanie zainicjowany przed wywołaniami innych funkcji.Dobrą rzeczą do zapamiętania i nie martwić się o to, że: zawsze wykonać raz w aplikacji.
init
init
wykonanie ma miejsce:init
funkcją pakietu „dzwoniącego”,main func
,var = [...] or cost = [...]
,Kiedy zaimportujesz pakiet, uruchomi on wszystkie swoje funkcje init, według kolejności .
Dam bardzo dobry przykład funkcji init. Doda to typy mime do standardowej biblioteki go o nazwie,
mime
a funkcja na poziomie pakietu użyjemime
pakietu standardowego bezpośrednio, aby uzyskać niestandardowe typy mime, które zostały już zainicjowane przy jegoinit
funkcji:Mam nadzieję, że pomogło Tobie i innym użytkownikom, nie wahaj się napisać ponownie, jeśli masz więcej pytań!
źródło
https://golang.org/ref/mem#tmp_4
źródło
init
będzie wywoływany wszędzie używa swojego pakietu (bez względu na import lub import pustych danych), ale tylko raz.to jest pakiet:
dowolny pakiet (pakiet główny lub dowolny pakiet testowy) zaimportuj go jako pusty:
lub zaimportuj go za pomocą func:
init zapisze się
0
tylko raz. pierwszy pakiet, który go używa, jego init initc uruchomi się przed init pakietu. Więc:Wywołania B, B wywołuje C, wszystkie mają funkcję init, inicjacja C będzie uruchamiana najpierw przed B, B przed A.
źródło
mutil init funkcja w jednym pakiecie wykonaj polecenie:
const i zmienna plikowa funkcja init () wykonuje się
funkcja init wykonuje kolejność według nazwy pliku asc
źródło
Funkcja init działa najpierw, a następnie główna. Służy do ustawienia czegoś przed uruchomieniem programu, na przykład:
Uzyskiwanie dostępu do szablonu, uruchamianie programu przy użyciu wszystkich rdzeni, sprawdzanie Goos i arch itp.
źródło