[go] 지속 시간에 정수를 곱하는 방법?

동시 고 루틴을 테스트하기 위해 함수에 한 줄을 추가하여 반환하는 데 임의의 시간이 걸립니다 (최대 1 초)

time.Sleep(rand.Int31n(1000) * time.Millisecond)

그러나 컴파일 할 때이 오류가 발생했습니다.

. \ crawler.go : 49 : 유효하지 않은 작업 : rand.Int31n (1000) * time.Millisecond (int32와 time.Duration이 일치하지 않는 유형)

어떤 아이디어? 지속 시간을 어떻게 곱할 수 있습니까?



답변

int32그리고 time.Duration다른 유형입니다. 당신은 변환해야 int32A와 time.Duration같은 time.Sleep(time.Duration(rand.Int31n(1000)) * time.Millisecond).


답변

올바른 형식으로 캐스트해야합니다 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 년으로 제한합니다.” 는 이는 다음 과 같이 부호있는 값으로 취급 된다는 것을 나타냅니다 .DurationDurationint64(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)


답변