Ответ 1
ВАЖНОЕ ОБНОВЛЕНИЕ:
Конечный ответ, безусловно, тот, который вы получили от Russ Cox, один из авторов Go, в списке рассылки golang-nuts. Тем не менее, я оставляю некоторые из моих предыдущих заметок ниже, они могут помочь понять некоторые вещи.
Кроме того, прочитав этот ответ, приведенный выше, я считаю, что псевдо-slash
∕
теперь может быть переведен на обычный/
слэш (например, middot переводится в точку) в более новые версии компилятора Go C чем тот, который я тестировал ниже, но у меня нет времени проверять.
Файл скомпилирован Внутренний компилятор языка Go Language Suite, который происходит в компиляторе Plan 9 C (1) (2) и имеет некоторые отличия (в основном расширения, AFAIK) до стандарта C.
Один из расширений состоит в том, что он позволяет символам UTF-8 в идентификаторах.
Теперь, в компиляторе Go Language Suite C, символ middot (·) обрабатывается особым образом, поскольку он преобразуется в обычную точку (.) в объектных файлах, которая интерпретируется внутренним компоновщиком языка Go Language Suite как символ разделителя пространства имен.
Пример
Для следующего файла
example.c
(обратите внимание: он должен быть сохранен как UTF-8 без спецификации):void ·Bar1() {} void foo·bar2() {} void foo∕baz·bar3() {}внутренний компилятор C создает следующие символы:
$ go tool 8c example.c $ go tool nm example.8 T "".Bar1 T foo.bar2 T foo∕baz.bar3Теперь, пожалуйста, обратите внимание, что я дал
·Bar1()
капиталB
. Это потому что таким образом я могу сделать его видимым для обычного кода Go - потому что он переводится на тот же самый символ, который компиляция следующего кода Go:package example func Bar1() {} // nm will show: T "".Bar1
Теперь, в отношении функций, которые вы назвали в вопросе, история идет дальше по кроличьей дыре. Я немного менее уверен, что я здесь, но я попытаюсь объяснить на основе того, что знаю. Таким образом, каждое предложение ниже этого пункта следует читать так, как будто оно было "AFAIK ", написанное только в конце.
Итак, следующая недостающая часть, необходимая для того, чтобы лучше понять эту загадку, заключается в том, чтобы узнать что-то еще о странном пространстве имен ""
и о том, как обрабатывается компоновщик Go suite. Пространство имен ""
- это то, что мы можем назвать "пустым" (потому что ""
для программиста означает "пустая строка" ), или, может быть, лучше, "пространство имен". И когда компоновщик видит импорт следующим образом:
import examp "path/to/package/example"
//...
func main() {
examp.Bar1()
}
то он принимает файл библиотеки $GOPATH/pkg/.../example.a
, а во время фазы импорта заменяет "на лету" каждый ""
с помощью path/to/package/example
. Итак, теперь в связанной программе мы увидим такой символ:
T path/to/package/example.Bar1