Вопрос об инициализации (выполнении) последовательности языка Go - PullRequest
0 голосов
/ 12 апреля 2019

Я новичок в Go.Я застрял в последовательности инициализации при запуске нескольких файлов go, включая пакеты, переменные и функцию init.

Насколько я знаю, есть несколько правил:

  1. Импортируемые пакеты и init функции должны вызываться в соответствии с их последовательностями появления.

  2. Если файл A импортирует файл B, а файл B импортирует файл C, инициализацияпоследовательность будет C-> B-> A.

  3. Зависимости всегда выполняются первыми.

  4. Пакет main всегда выполняется вlast.

Есть пример, который меня смущает (мне сказали, что последовательность инициализации представлена ​​так: от маленьких чисел до больших чисел, как 1.1 выполняется до 1.2, 1.2 - этовыполнено до 2.1 и т. д.)

// p1.go

package p1

import "fmt"         //1.1

var x float32 = 1.2   //1.2

func init()  {        //1.3

       fmt.Printf("p1 package, x:%f\n", x)    //1.4
}

func Donothing() {

       fmt.Println("do nothing.\n")
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// a.go

package main

import "fmt"

var WhatIsThe1 = AnswerToLife(2.1) //2.1
var WhatIsThe2 = AnswerToLife(2.2) //2.2
var WhatIsThe3 = AnswerToLife(2.3) //2.3

func init() { //3.1


       fmt.Printf("init WhatIsThe in a.go `s init 3.1: %d\n", 2)

}

func init() { //3.2


       fmt.Printf("init WhatIsThe in a.go`s init 3.2: %d\n", 3)

}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// testinit.go

package main

import "p1" //1
import "fmt"

var WhatIsThe4 = AnswerToLife(2.4) //2.4
var WhatIsThe5 = AnswerToLife(2.5) //2.5
var WhatIsThe6 = AnswerToLife(2.6) //2.6

func AnswerToLife(index float32) float32 {

       fmt.Printf("init package level variable, WhatIsThe: %f\n", 
index)
       return index
}

func init() { //3.3

       fmt.Printf("init WhatIsThe in testinit.go`s init3.3: %d\n", 0)

}

func init() { //3.4

       fmt.Printf("init WhatIsThe in testinit.go`s init3.4: %d\n", 1)

}

func main() { //4

       p1.Donothing() //5
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// z.go

package main

import "fmt"

var WhatIsThe7 = AnswerToLife(2.7) //2.7
var WhatIsThe8 = AnswerToLife(2.8) //2.8
var WhatIsThe9 = AnswerToLife(2.9) //2.9

func init() { //3.5


       fmt.Printf("init WhatIsThe in z.go`s init 3.5: %d\n", 4)

}

func init() { //3.6


       fmt.Printf("init WhatIsThe in z.go`s init 3.6: %d\n", 5)

}

Я запутался в этих вещах:

  1. Когда файл объявляет пакет main, эточто за отсутствие функции main?

  2. Если существует несколько пакетов main (s), каковы их отношения?

  3. Как я знаю из других языков, таких как Python, Javascript и т. Д., Должен быть один "основной файл".Каков язык Go?

  4. Какова последовательность инициализации всего пакета main (s)?

  5. Я запутался в последовательности2.1 ~ 2.9, почему они выполняются последовательно вместо выполнения этих init функций в файлах a.go, testinit.go и z.go?

1 Ответ

0 голосов
/ 12 апреля 2019

спецификация говорит:

Полная программа создается путем связывания одного не импортированного пакета, называемого основным, со всеми пакетами, которые она импортирует, транзитивно. Основной пакет должен иметь имя пакета main и объявлять функцию main, которая не принимает аргументов и не возвращает значения.

func main() { … }

Выполнение программы начинается с инициализации основного пакета и последующего вызова функции main. Когда этот вызов функции возвращается, программа завершается. Он не ждет завершения других (не основных) программ.

Обратите внимание, что существует различие между основным пакетом и пакетами с именем main.

  1. Основной пакет должен иметь функцию main в одном, если файлы пакета. В противном случае файл в пакете с именем main не должен иметь функцию main.

  2. Выполнение программы начинается с основного пакета, как определено выше. Другие пакеты с именем main не имеют специального статуса.

  3. Может быть несколько main пакетов. Только один пакет будет соответствовать требованиям основного пакета.

  4. Порядок инициализации пакета зависит от отношения импорта между пакетами. Имя любого пакета не играет никакой роли в определении порядка инициализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...