Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does %T not print the type of my constant?

I'm just learning golang using the official tour/tutorial. In one of the examples, I see a note that says An untyped constant takes the type needed by its context.

I'm trying this:

package main

import "fmt"

const (
    // Create a huge number by shifting a 1 bit left 100 places.
    // In other words, the binary number that is 1 followed by 100 zeroes.
    Big = 1 << 100
)

func main() {
    fmt.Printf("Big is of type %T\n", Big)
}

But this fails when I run it, with:

# command-line-arguments
./compile63.go:12:13: constant 1267650600228229401496703205376 overflows int

Why am I unable to discover the type of the constant this way? (Please note I'm a total noob and quite possibly haven't yet discovered enough about the language to be able to solve this myself).

like image 374
scorpiodawg Avatar asked Jun 20 '18 06:06

scorpiodawg


1 Answers

func Printf

func Printf(format string, a ...interface{}) (n int, err error)

Printf formats according to a format specifier and writes to standard output. It returns the number of bytes written and any write error encountered.


The Go Programming Language Specification


Variable declarations

A variable declaration creates one or more variables, binds corresponding identifiers to them, and gives each a type and an initial value.

If a list of expressions is given, the variables are initialized with the expressions following the rules for assignments. Otherwise, each variable is initialized to its zero value.

If a type is present, each variable is given that type. Otherwise, each variable is given the type of the corresponding initialization value in the assignment. If that value is an untyped constant, it is first converted to its default type; if it is an untyped boolean value, it is first converted to type bool. The predeclared value nil cannot be used to initialize a variable with no explicit type.


Constants

Constants may be typed or untyped. Literal constants, true, false, iota, and certain constant expressions containing only untyped constant operands are untyped.

A 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. It is an error if the constant value cannot be represented as a value of the respective type.

An untyped constant has a default type which is the type to which the constant is implicitly converted in contexts where a typed value is required, for instance, in a short variable declaration such as i := 0 where there is no explicit type. The default type of an untyped constant is bool, rune, int, float64, complex128 or string respectively, depending on whether it is a boolean, rune, integer, floating-point, complex, or string constant.


Numeric types

A numeric type represents sets of integer or floating-point values. Some predeclared architecture-independent numeric types:

int32       the set of all signed 32-bit integers (-2147483648 to 2147483647)
int64       the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)

The value of an n-bit integer is n bits wide and represented using two's complement arithmetic.

There are also some predeclared numeric types with implementation-specific sizes:

uint     either 32 or 64 bits
int      same size as uint

Big is an untyped constant. There is no type to discover. It is given a type when used in a variable or assignment. The default type for the untyped constant Big is int.

const Big = 1 << 100

In Go, all arguments are passed by value as if by assignment. For fmt.Printf, the second argument is of type interface{}. Therefore, equivalently,

var arg2 interface{} = Big  // constant 1267650600228229401496703205376 overflows int
fmt.Printf("Big is of type %T\n", arg2)

The default type for an untyped integer constant is int. Overflow is a compile-time error.


For example,

package main

import "fmt"

const (
    // Create a huge number by shifting a 1 bit left 100 places.
    // In other words, the binary number that is 1 followed by 100 zeroes.
    Big = 1 << 100
)

func main() {
    var arg2 interface{} = Big
    fmt.Printf("Big is of type %T\n", arg2)

    fmt.Printf("Big is of type %T\n", Big)
}

Playground: https://play.golang.org/p/9tynPTek3wN

Output:

prog.go:12:6: constant 1267650600228229401496703205376 overflows int
prog.go:15:13: constant 1267650600228229401496703205376 overflows int

Reference: The Go Blog: Constants

like image 95
peterSO Avatar answered Nov 09 '22 09:11

peterSO