Go Static Typing 'Magic'

As I understand Go more, some of the concepts tend to make my head hurt. Sometimes, innocent examples in various tutorials hide such deep concepts, that it takes a while for me to decode it all.

Here is an example. In various tutorials, pauses are made using time.Sleep().

The first time I saw an example like the following, it made me stop in my tracks.

package main

import (

func main() {
	time.Sleep(100 * time.Millisecond)

Here is the signature of time.Sleep

func Sleep(d Duration)

And here is what Duration and time.Millisecond means.

type Duration int64

const (
        Nanosecond  Duration = 1
        Microsecond          = 1000 * Nanosecond
        Millisecond          = 1000 * Microsecond
        Second               = 1000 * Millisecond
        Minute               = 60 * Second
        Hour                 = 60 * Minute

Coming from my past experience with other languages, my question was, in a strongly typed language like Go:

  1. How does 100 * time.Millisecond work? Aren’t they entirely two different types? And I know that Go doesn’t support operator overloading. So how does Go know how to use the operator * between a Duration and what looks like an int. My first guess was that Go was converting the duration time.Millisecond to an int to make the multiplication work, like in other language.
  2. Even if somehow the multiplication worked, how is the result satisfying the type requirement for the parameter passed to Sleep() which requires a Duration.

Turns out my guess was wrong.

There are a couple of points in the spec that explains what is happening.

So, if I have got it right:

  1. Go will convert the untyped integer value 100 to the type Duration.
  2. Since both have the underlying type of integer, it will follow the integer operator rules for *
  3. The result will be converted to the type of time.Duration
Jetbrains Finalizes Name for their Go IDE Settling on Vscode for Go