Pull to refresh

Comments 19

Заголовок спойлера
1 Оба раза пустой массив. Адреса совпадают.
2 Не скомпилируется
3 Функции будут вызваны в случайном порядке, но в соответствии с иерархии начиная с нижнего модуля (package_3) и заканчивая верхним (package_1)
4 1,2,3,4,5
5 В stdout ничего не выведется, но процесс завершится успешно
6 2
7 8 12
Можно было просто ссылку на play.golang.org скинуть :)
Попортил фан
Небольшое дополнение по 3: в принципе, порядок вызова init-функций в рамках одного пакета строго не регламентирован, в спецификации написано:
To ensure reproducible initialization behavior, build systems are encouraged to present multiple files belonging to the same package in lexical file name order to a compiler.
Поэтому, при запуске мы увидем:
p3_bash.go
p3_sh.go
p3_zsh.go
p2_a.go
p1_a.go
p1_b.go

Я, конечно же, (почти) всё уже проверил сам на play.golang.org, но вот мои оригинальные ответы:

Скрытый текст
1. Оба раза пустой массив. Адреса совпадают.
2. Не скомпилируется (но я думал, что по причине того, что capacity не может быть меньше длины, а не потому что длина обязательна)
3. Функции будут вызваны в случайном порядке, но в соответствии с иерархии начиная с нижнего модуля (package_3) и заканчивая верхним (package_1)
4. 1,2,3,0,1 — кстати говоря, такого варианта у вас нет, видимо опечатка
5. В stdout ничего не выведется, но процесс завершится успешно — но за такой код я бы наказывал
6. 2
7. 8 14 — строго говоря, программисты на Го вряд ли должны знать ширину китайских иероглифов в UTF-8. Тут скорее важно, что сами ответы будут разные при итерации по символам и по байтам.
Почти всё верно) по ответам:
3. дополнение
4. iota соответствует индексу ConstSpec внутри const-блока, поэтому второе использование в том же блоке не сбрасывает значение в 0.
5. На этот пример вдохновил доклад Пайка :)
8. Полностью согласен, главное знать в чём отличие)
Скрытый текст
1) передача слайса значением. Изменить данные мы конечно сможем, но длинну нет, а она 0.
2) никогда не использовал тройную запись, могу только предположить, что размерность 4 будет меньше длинны здесь: [::4]
3) конечно, иерархия должна присутствовать, иначе мы рискуем использовать подпакет, который не инициализирован.
4) iota сбрасывается каждый блок const, а он тут один.
5) в stdout, собственно, ничего и не выводим. Но это ж не причина для паники)
6) тут и объяснять ничего не надо, достаточно заменить return x на return, для тех, кто не заметил именованные возвратные значения
7) да кто их знает, сколько байт один иероглиф займет?)
Изменить данные мы конечно сможем, но длинну нет, а она 0.

Но, кстати, мы можем таки получить доступ к данным:
fmt.Printf("%v %p\n", arr[:1], &arr)

Спасибо, вот вам в благодарность тоже задачка:


package main

import "fmt"

func main() {
    for i := 0; i < 3; i++ {
        defer func() {
            fmt.Println(i)
        }()
    }
}
Чтобы ваш код работал так, как возможно, предполагается (ну на первый взгляд), надо после инициализации цикла добавить i:=i, а ещё лучше вот так:

package main

import "fmt"

func main() {
    for i := 0; i < 3; i++ {
        defer func(i int) {
            fmt.Println(i)
        }(i)
    }
}
Думаю в этом и фишка, что код работает не так как кажется на первый взгляд…
Как раз он работает именно так, как кажется на первый взгляд — печатает 3 раза одно и то же число :). Другой вопрос, что наверное в цикле defer вызывать – не лучшая идея :).
А ещё лучше просто вот так:

package main

import "fmt"

func main() {
    for i := 0; i < 3; i++ {
            defer fmt.Println(i)
    }
}


Потому что аргументы для вызова функции вычисляются на момент вызова defer
Пожалуйста) ждите след. поста с задачками для PHP)
Вопрос знатокам Go по именным возвращаемым значениям, вы можете мне указать где в спецификации описывается следующее поведение:
package main

import (
    "fmt"
)

func test() (x int) {
    x = 1
    defer func () {
        x++
    } ()

    return 2
}

func main() {
    fmt.Println(test())
}


Спасибо
Отложенные ф-ции выполняются после возвращения из основной, т.е. сначала будет выполнено return 2 (x = 2), а затем x++.
Спасибо за ответ. Я имел в виду где описывается поведение `return 2` == `x = 2; return x`?
Sign up to leave a comment.