I have a loop where I start by a time.Time and I what to add a minute.
for idx := range keys {
var a = idx * time.Minute
var t = tInit.Add(time.Minute * a)
fmt.Println(t, idx)
}
Here is my error
invalid operation: idx * time.Minute (mismatched types int and time.Duration)
The operands to numeric operations must have the same type. Convert the int
value idx
to a time.Duration
: var a = time.Duration(idx) * time.Minute
As a developer in other programing languages I found this the most counterintuitive and illogical way of doing it. I worked in Scala in the last 10 years, and it could be as simple as this:
val a = idx minutes
compared that, the Go way:
var a = time.Duration(idx) * time.Minute
is more verbose, but that wouldn't be the end of the world.
The problem is that multiplying a Duration with another Duration doesn't make any sense if what you want is to obtain another Duration as a result, because from a physical point of view that would be measured in something like seconds squared.
According to the documentation time.Minute is a constant:
const (
Nanosecond Duration = 1
Microsecond = 1000 * Nanosecond
Millisecond = 1000 * Microsecond
Second = 1000 * Millisecond
Minute = 60 * Second
Hour = 60 * Minute
)
And all those are defined in terms of the Duration type which is an alias for int64:
type Duration int64
From what I see is perfectly fine to multiply an integer literal with each one of these constants, after all that's how each one is defined in relation to the others.
So, to recap why is 60 * time.Second
valid syntax (and makes perfect sense), but:
var secondsInAMinute := 60
var oneMinute = secondsInAMinute * time.Second
is invalid. This doesn't make any sense.
All those constants are of type Duration. That means they are measured in units of time (multiples of one nanosecond to be precise).
So, it seems the "correct" way to do it (correct in the sense that it compiles and works) doesn't make any physical sense. Let's look at this again:
var a = time.Duration(idx) * time.Minute
So, we are multiplying time.Duration(idx) with time.Minute.
The type for time.Minute
is Duration which should be measured with a time unit. In physics it the accepted unit for time is the second. It seems Go uses integer nanoseconds instead, so time.Minute represents a Duration, represented internally in nanoseconds. That's fine.
The problem is that time.Duration(idx)
also "converts" the integer idx to a Duration, so in physics it would also be represented as a unit of time, like seconds. So, accordingly, time.Duration(idx), in my opinion, represents idx nanoseconds
in Go.
So, basically, when we write time.Duration(idx) * time.Minute
we are muliplying idx nanoseconds
(idx * 0.0000000001 seconds) with one minute
(60 seconds).
So, from a physical point of view time.Duration(idx) * time.Minute
would represent idx * 0.000000001 seconds * 60 seconds
. Or, simplified, idx * 0.00000006 seconds squared
.
Now, in what world is idx * 0.00000006 seconds squared
equal to idx * 1 minute
?
So, now I know, in Go, if you want to apply a multiplier to a duration, you have to multiply that Duration to another Duration, and divide that in your mind with one millisecond
so that all this mess can still makes any kind of physical sense.
I understand that all these unit inconsistencies are the result of the "The operands to numeric operations must have the same type." constraint. But that doesn't make it more logical or less annoying. In my opinion that restriction of the Go language should be removed.
But, for anyone that was lost in my explanations, let's see how illogical all this is with a concrete code example:
package main
import (
"fmt"
"time"
)
func main() {
var oneMinute = 1 * time.Minute
var oneNanosecond = 1 * time.Nanosecond
var oneMinuteTimesOneNanoSecond = oneMinute * oneNanosecond
fmt.Println(oneMinuteTimesOneNanoSecond)
}
The result is exactly what I expected from this nonsensical way of doing time calculations:
1m0s
I'll learn to live with this, but I will never like it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.