답변:
int32
그리고 time.Duration
다른 유형입니다. 당신은 변환해야 int32
A와 time.Duration
같은 time.Sleep(time.Duration(rand.Int31n(1000)) * time.Millisecond)
.
time.Sleep(time.Second * 2)
Duration
* Duration
=로 곱셈을 캐스팅해야합니다 Duration
. Duration
* int
= Duration
.
int64(...) * Duration
캐스트하는 것보다 훨씬 더 의미있는 이것에 대해 되돌아 보면 Duration
, 이것은 유닛이 어떻게 작동 해야하는지에 대한 기본적인 위반입니다. 슬프게도 작동하지 않습니다. 정말 Duration * Duration
끔찍한 일 을 해야합니다 .
올바른 형식으로 캐스트해야합니다 Playground.
yourTime := rand.Int31n(1000)
time.Sleep(time.Duration(yourTime) * time.Millisecond)
잠자기 문서를 확인 하는 경우 func Sleep(d Duration)
지속 기간이 매개 변수로 필요하다는 것을 알 수 있습니다 . 귀하의 rand.Int31n의 반환 int32
.
time.Sleep(100 * time.Millisecond)
컴파일러가 여기에서 상수 100이 지속 시간을 의미한다는 것을 이해할 정도로 똑똑하기 때문에 예제의 줄이 작동합니다 ( ) . 그러나 변수를 전달하면 변수를 캐스트해야합니다.
Go에서는 동일한 유형의 변수를 곱할 수 있으므로 표현식의 두 부분이 모두 동일한 유형이어야합니다.
가장 간단한 방법은 곱하기 전에 정수를 지속 시간으로 캐스팅하는 것이지만 단위 의미를 위반합니다. 단위로 기간을 기간별로 곱하는 것은 무엇입니까?
차라리 time.Millisecond를 int64로 변환 한 다음 밀리 초 수를 곱한 다음 시간으로 캐스트합니다.
time.Duration(int64(time.Millisecond) * int64(rand.Int31n(1000)))
이런 식으로 표현의 어떤 부분도 그 유형에 따라 의미있는 가치를 가진다고 말할 수 있습니다. int64(time.Millisecond)
부분은 차원이없는 값입니다. 원래 값에서 가장 작은 시간 단위 수입니다.
약간 더 간단한 길을 걷는 경우 :
time.Duration(rand.Int31n(1000)) * time.Millisecond
곱셈의 왼쪽 부분은 넌센스입니다. "time.Duration"유형의 값으로 해당 유형과 관련이없는 것을 보유합니다.
numberOfMilliseconds := 100
// just can't come up with a name for following:
someLHS := time.Duration(numberOfMilliseconds)
fmt.Println(someLHS)
fmt.Println(someLHS*time.Millisecond)
그리고 그것은 의미론뿐만 아니라 유형과 관련된 실제 기능이 있습니다. 이 코드는 다음을 인쇄합니다.
100ns
100ms
흥미롭게도 여기의 코드 샘플은 가장 간단한 코드를 사용하며 지속 기간 변환의 오해를 불러 일으키는 의미가 동일합니다 : https://golang.org/pkg/time/#Duration
초 : = 10
fmt.Print (time.Duration (seconds) * time.Second) // 10 초를 인쇄합니다
Go에는 Duration
유형이 있습니다. 단위를 명시 적으로 정의하면 실제 문제를 예방할 수 있습니다.
또한 Go의 엄격한 유형 규칙으로 인해 Duration에 정수를 곱할 수 없습니다 . 일반적인 유형을 곱하려면 캐스트 를 사용해야합니다 .
/*
MultiplyDuration Hide semantically invalid duration math behind a function
*/
func MultiplyDuration(factor int64, d time.Duration) time.Duration {
return time.Duration(factor) * d // method 1 -- multiply in 'Duration'
// return time.Duration(factor * int64(d)) // method 2 -- multiply in 'int64'
}
공식 문서는 방법 # 1을 사용하는 방법을 보여줍니다 :
정수 단위의 기간을 기간으로 변환하려면 다음을 곱하십시오.
seconds := 10
fmt.Print(time.Duration(seconds)*time.Second) // prints 10s
그러나 물론 지속 시간에 지속 시간을 곱하면 지속 시간이 생성되어서는 안됩니다. 예를 들어 5 밀리 초에 5 밀리 초를 곱하면 6h56m40s
됩니다. 5 초를 제곱하려고하면 오버플로가 발생합니다 (상수로 수행하면 컴파일되지 않음).
그건 그렇고, 나노초 단위 의 int64
표현은 "가장 큰 표현 가능 기간을 약 290 년으로 제한합니다." 는 이는 다음 과 같이 부호있는 값으로 취급 된다는 것을 나타냅니다 .Duration
Duration
int64
(1<<(64-1))/(1e9*60*60*24*365.25) ~= 292
// A Duration represents the elapsed time between two instants
// as an int64 nanosecond count. The representation limits the
// largest representable duration to approximately 290 years.
type Duration int64
그래서 우리는 알고 있기 때문에의 기본 표현하는 것이 Duration
이다 int64
사이의 캐스트를 수행 int64
하고 Duration
합리적인 NO-OP입니다 - 유형을 혼합에 대한 언어 규칙을 만족하는 경우에만 필요하며 이후의 곱셈 연산에 영향을주지 않습니다.
순도 때문에 주조를 좋아하지 않으면 위에 표시된 것처럼 함수 호출에 묻습니다.
변수를 시간에 곱하기 위해 다음 코드를 사용하여 두 번째
oneHr:=3600
addOneHrDuration :=time.Duration(oneHr)
addOneHrCurrTime := time.Now().Add(addOneHrDuration*time.Second)
time.Duration
변수 를 사용하는 좋은 방법이 아닙니다 . addOneHrDuration
시간 변수 의 이름을 지정한 time.Duration
다음 1 시간이 아닌 3600ns로 설정하십시오. A의 time.Duration
기본 단위는 나노초입니다. 실제로 1 시간 동안 작업하려면 const oneHourDuration = 60 * time.Hour
(또는 3600 * time.Second
또는 time.Hour
) 와 같은 작업을 수행 할 수 있습니다.
rand.Seed(time.Now().Unix())