Что это означает, что константа должна быть нетипизирована в golang?

spec говорит, что:

Константы могут быть напечатаны или неттипированы

У меня есть небольшое сомнение в моем понимании. Рассмотрим этот пример в спецификации:

const l = "hi"             // l == "hi"  (untyped string constant)
const m = string(k)        // m == "x"   (type string)

Спектр говорит:

константе

может быть задан тип явно объявлением константы или преобразования или неявно при использовании в объявлении переменной или назначение или как операнд в выражении

В этом утверждении, почему не набирается l, поскольку оно явно является объявлением константы?

Это поведение более ясное с другим примером

type Foo string
func f(a Foo) {}

func main() {
  f("sarkozy")

  const t = "julie gayet"
  f(t)

  s := "hollande"
  //compile error
  // f(s)

  f(Foo(s)) // ok
}

Является ли причина, по которой f("sarkozy") компилируется из-за этого утверждения о Assignability в spec?

x - нетипизированная константа, представляемая значением типа T.

Мой аргумент следующий:

  • "sarkozy" - нетипизированный литерал.
  • Таким образом, "sarkozy", представляемый Foo, означает, что я могу ввести coerce как это Foo("sarkozy")
  • f(s) терпит неудачу, потому что s не является нетипизированным.

Ответ 1

Почему не набирается, так как это явно декларация констант?

Да, это явно постоянное объявление, так как в вашей цитате сказано:

константе

может быть задан тип явно объявлением константы

Однако в вашем случае нет явно заданного типа. У вас может быть только неявно заданный тип, когда "используется в объявлении переменной или присваивании или в качестве операнда в выражении".

Является ли причина, по которой f ( "sarkozy" ) компилируется из-за этого утверждения о Assignability в spec?

Да, причина, по которой компиляция f("sarkozy") заключается в том, что нетипизированная константа "sarkozy" имеет тип, неявно используемый при использовании в качестве операнда в выражении, например, в вашем случае.

"sarkozy" неявно задается тип Foo

Итак, почему f(s) не компилируется? (хорошо, этого не было в вопросе, но вопрос остается)

В вашем аргументе указано, что: "f (s) терпит неудачу, потому что s не является нетипизированным".

Верно, что s не является нетипизированным. s - переменная, а не константа, а переменные не могут быть отписаны.

Состояние спецификаций Go для Объявления переменных:

Если тип отсутствует и соответствующее выражение оценивается в нетипизированной константе, тип объявленной переменной соответствует описанию в разделе "Объявления".

И это относится к тому, что я понимаю, к следующему:

константа сначала преобразуется в тип bool, rune, int, float64, complex128 или string соответственно, в зависимости от того, является ли значение логической, рунической, целочисленной, с плавающей точкой, сложной или строковой константой.

Итак, следующая строка:

s := "hollande"

объявит переменную (не константу) s типа string, потому что правое выражение является нетипизированной строковой константой. Тип неявно указывается во время объявления переменной, а не путем анализа того, какой контекст он будет использовать в дальнейшем.

f (s) приведет к ошибке компиляции, потому что вы пытаетесь использовать значение типа string, где ожидается значение типа Foo.