muhajirframe
muhajirframe

Reputation: 61

Confused with Type conversions in golang

I recently tried to learn golang. But I got confused with this code from https://tour.golang.org/basics/13.

package main

import (
    "fmt"
    "math"
)

func main() {
    var x, y int = 3, 4
    var f float64 = math.Sqrt(float64(x*x + y*y))
    var z uint = uint(f)
    fmt.Println(x, y, z)
}

That one works well. Then I tried

var f = math.Sqrt(9 + 16)

which also works. But when I change it to var f = math.Sqrt(x*x + y*y) why is it not working? It says cannot use x * x + y * y (type int) as type float64 in argument to math.Sqrt

I have javascript background, and I somehow can't understand the code above.

Upvotes: 3

Views: 9940

Answers (2)

Volker
Volker

Reputation: 42458

But when we pass a number directly, it automatically converted?

No, not really *). Your "direct numbers" are called "constants" in Go and constants are often "untyped" and (almost) of arbitrary precision. There are special rules for constants: A constant 5 and the integer a defined by a := 5 behave differently because 5 is a constant with special rules and not an int.

Constant expressions like 9 + 16 are evaluated at compile time like if you had typed 25. This 25 is still a (constant.

While Go does not have automatic type conversions for types it does have automatic conversions from constants to several types. The constant 25 can be converted to float64 or int, uint8 or even complex128 automatically.

Please read the blog post https://blog.golang.org/constants and the official language spec for a full explanation and all details: https://golang.org/ref/spec#Constants . This explains the strange notion of "untyped integer" better than I could.

*) "not really" because it is not helpful to think about it that way. The distinction of constants is special in Go: Most other languages tread 3+5 as a sum of two ints resulting in an int while Go sees two untyped integer constants and evaluates this expression into a new arbitrary precision, untyped constant. Only later are constants converted to actual integers.

Upvotes: 4

Akavall
Akavall

Reputation: 86306

The math.Sqrt function signature:

func Sqrt(x float64) float64

requires that you pass float64

In this case:

var f float64 = math.Sqrt(float64(x*x + y*y))

You are converting to float64 directly

In this case:

var f = math.Sqrt(x*x + y*y)

you are passing an int, when float64 is required.

In this case:

var f = math.Sqrt(9 + 16)

The compiler is able to infer the type, and pass float64 for you.

Upvotes: 7

Related Questions