1

I'm getting an invalid operation: *timeout * time.Second (mismatched types int and time.Duration) error when trying to run something similar to this

timeout := flag.Int("timeout", 30, "The time limit for answering questions.")
flag.Parse()
timeoutCh := time.After(*timeout * time.Second)

Just to be sure, I checked the type of *timeout using reflect.TypeOf() and it is in fact an int. But if I do timeoutCh := time.After(30 * time.Second) or use any other int value the code works.

What am I missing here?

2 Answers2

2
timeoutCh := time.After(time.Duration(*timeout) * time.Second)

You have to convert *timeout which is type int to type time.Duration. The reason why time.After(30 * time.Second) works is that 30 is untyped and is converted to the type of time.Second which is time.Duration. See https://golang.org/ref/spec#Operators. Similarly this code works

x := uint(42)
if x == 42 {
    println("works!")
}

but this code won't compile

x := uint(42)
y := 42 // defaults to type int
if x == y {
    println("this won't complile!")
}
Jake Burkhead
  • 6,435
  • 2
  • 21
  • 32
  • "Except for shift operations, if one operand is an untyped constant and the other operand is not, the constant is converted to the type of the other operand." I didn't know that! Thank you! – Wilder Galvao Mar 24 '18 at 03:19
2

You cannot multiply two different types, so you will need to convert the integer to a time.Duration type. You can do that by simply casting it like this:

time.Duration(*timeout)

A "unit" of time is technically a nanosecond and time.Second is one seconds worth of nanoseconds. The math works out though so you can simply say something like this for 3 seconds:

time.Duration(3) * time.Second
t j
  • 7,026
  • 12
  • 46
  • 66
John Leon
  • 44
  • 1
  • 3