Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does it mean for a constant to be untyped?

Tags:

go

The Go Programming Language Specification says that:

Constants may be typed or untyped

I am having a little doubt in my understanding. Consider this example in the spec:

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

The spec says:

constant may be given a type explicitly by a constant declaration or conversion, or implicitly when used in a variable declaration or an assignment or as an operand in an expression

By this statement, why isn't l typed since it is clearly a constant declaration?

This behaviour is clearer with another example

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
}

Is the reason that f("sarkozy") compiles be due to this statement on Assignability in the spec?

x is an untyped constant representable by a value of type T.

My argument is the following:

  • "sarkozy" a an untyped literal.
  • Thus "sarkozy" being representable by Foo means I can type coerce like this Foo("sarkozy")
  • f(s) fails because s is not untyped.
like image 355
canadadry Avatar asked Mar 25 '14 02:03

canadadry


People also ask

What is an untyped constant?

An untyped constant has no limits. When it's used in a context that requires a type, a type will be inferred and a limit applied. const big = 10000000000 // Ok, even though it's too big for an int. const bigger = big * 100 // Still ok. var i int = big / 100 // No problem: the new result fits in an int.

What is an untyped string?

Instead, literals are Untyped string constants. It is a string (more correctly, its default type is string ), but it is not a Go value and therefore has no type until it is assigned or used in a context that is typed.

How do untyped constants interact with Go's typing system?

Untyped Constants They are not given a fixed type yet, like int32 or float64 or string , that would force them to obey Go's strict type rules. Note that, Although the value 1 is untyped, it is an untyped integer. So it can only be used where an integer is allowed.

What is an unnamed constant?

Unnamed constants are all boolean, numeric and string values. Like unnamed constants, named constants can also be only boolean, numeric and string values. The keyword const is used to declare named constants. The following program contains some constant declarations.


1 Answers

Why isn't l typed since it is clearly a constant declaration?

Yes, it is clearly a constant declaration, as your quote says:

constant may be given a type explicitly by a constant declaration

However, in your case there is no explicitly given type. You can only have an implicitly given type when "used in a variable declaration or an assignment or as an operand in an expression".

Is the reason that f("sarkozy") compiles be due to this statement on Assignability in the spec?

Yes, the reason that f("sarkozy") compiles is because the untyped constant of "sarkozy" has a type given implicitly when used as an operand in an expression such as in your case.

"sarkozy" is implicitly given the type of Foo

So why doesn't f(s) compile? (okay, that was not in the question, but the question remains)

Your argument states that: "f(s) fails because s is not untyped."

True that s is not untyped. s is a variable and not a constant, and variables cannot be untyped.

The Go specs states for Variable Declarations:

If the type is absent and the corresponding expression evaluates to an untyped constant, the type of the declared variable is as described in §Assignments.

And that refers, from what I understand to the following:

the constant is first converted to type bool, rune, int, float64, complex128 or string respectively, depending on whether the value is a boolean, rune, integer, floating-point, complex, or string constant.

So, the following line:

s := "hollande"

will declare the variable (not constant) s of type string because the right-hand expression is an untyped string constant. The type is implicitly given during the declaration of the variable, not by analyzing what context it which it later on will be used.

f(s) will then result in a compile error because you try to use a value of type string where a value of type Foo is expected.

like image 75
ANisus Avatar answered Oct 05 '22 03:10

ANisus