Programing

Go에서 리터럴 * int64를 어떻게 수행합니까?

crosscheck 2020. 10. 14. 07:30
반응형

Go에서 리터럴 * int64를 어떻게 수행합니까?


*int64필드 가있는 구조체 유형이 있습니다.

type SomeType struct {
    SomeField *int64
}

내 코드의 어느 시점에서 나는 이것의 리터럴을 선언하고 싶습니다 (예를 들어, 값이 0이어야한다는 것을 알고 있거나 0을 가리킬 때 내가 의미하는 바를 알 수 있습니다)

instance := SomeType{
    SomeField: &0,
}

... 이것은 작동하지 않는 것을 제외하고

./main.go:xx: cannot use &0 (type *int) as type *int64 in field value

그래서 나는 이것을 시도

instance := SomeType{
    SomeField: &int64(0),
}

...하지만 이것도 작동하지 않습니다

./main.go:xx: cannot take the address of int64(0)

어떻게해야합니까? 내가 생각 해낼 수있는 유일한 해결책은 자리 표시 자 변수를 사용하는 것입니다.

var placeholder int64
placeholder = 0

instance := SomeType{
    SomeField: &placeholder,
}

참고 : &0구문이 작동 벌금을 그것이 * INT는 대신 때 *int64. 편집 : 그렇지 않습니다. 이렇게되어 미안합니다.

편집하다:

분명히 내 질문에 너무 모호한 부분이있었습니다. 내가 할 수있는 방법을 찾고 있어요 그대로 상태*int64 . 이것은 생성자 내부에서 사용하거나 리터럴 구조체 값을 명시하거나 다른 함수에 대한 인수로 사용할 수도 있습니다. 그러나 도우미 기능이나 다른 유형을 사용하는 것은 내가 찾고있는 솔루션이 아닙니다.


Go 언어 사양 ( 주소 연산자 )은 숫자 상수의 주소를 허용하지 않습니다 ( 유형이 지정되지 않았거나 입력 된 상수가 아님).

피연산자는 주소를 지정할 수 있어야합니다 . 즉, 변수, 포인터 간접 지정 또는 슬라이스 인덱싱 작업 중 하나 여야합니다 . 또는 주소 지정 가능한 구조체 피연산자의 필드 선택자; 또는 주소 지정 가능한 배열의 배열 인덱싱 작업입니다. 주소 지정 요구 사항에 대한 예외로, x[의 표현에서 &x]는 복합 리터럴 일 수도 있습니다 (괄호 안에 있음) .

이것이 허용되지 않는 이유에 대해서는 관련 질문 : Find address of constant in go를 참조하십시오 . 유사한 질문 (비슷하게 주소를 가져갈 수 없음) : Go에서 작업 결과에 대한 참조를 어떻게 저장할 수 있습니까?

옵션 ( Go Playground 에서 모두 시도 ) :

1) 함께 new()

내장 new()함수를 사용하여 새로운 0 값을 할당 int64하고 주소를 얻을 수 있습니다.

instance := SomeType{
    SomeField: new(int64),
}

그러나 이것은 모든 유형의 0 값에 대한 포인터를 할당하고 얻는 데만 사용할 수 있습니다.

2) 도우미 변수 사용

0이 아닌 요소에 대해 가장 간단하고 권장되는 것은 주소를 가져올 수있는 도우미 변수를 사용하는 것입니다.

helper := int64(2)
instance2 := SomeType{
    SomeField: &helper,
}

3) 도우미 기능 포함

또는 이것을 여러 번 필요로하는 경우 다음을 할당하고 반환하는 도우미 함수를 만들 수 있습니다 *int64.

func create(x int64) *int64 {
    return &x
}

그리고 그것을 사용 :

instance3 := SomeType{
    SomeField: create(3),
}

실제로 아무것도 할당하지 않았고 Go 컴파일러는 함수 인수의 주소를 반환했을 때 할당했습니다. Go 컴파일러는 이스케이프 분석을 수행하고 함수를 이스케이프 할 수있는 경우 스택 대신 힙에 지역 변수를 할당합니다. 자세한 내용 은 Go 함수에서 로컬 배열 조각을 안전하게 반환합니까?를 참조하십시오.

4) 한 줄 익명 기능 사용

instance4 := SomeType{
    SomeField: func() *int64 { i := int64(4); return &i }(),
}

또는 (짧은) 대안으로 :

instance4 := SomeType{
    SomeField: func(i int64) *int64 { return &i }(4),
}

5) 슬라이스 리터럴, 인덱싱 및 주소 가져 오기

*SomeField이외의 사람 이되고 싶다면 0주소를 지정할 수있는 것이 필요합니다.

여전히 그렇게 할 수 있지만 그것은 추합니다.

instance5 := SomeType{
    SomeField: &[]int64{5}[0],
}
fmt.Println(*instance2.SomeField) // Prints 5

What happens here is an []int64 slice is created with a literal, having one element (5). And it is indexed (0th element) and the address of the 0th element is taken. In the background an array of [1]int64 will also be allocated and used as the backing array for the slice. So there is a lot of boilerplate here.

6) With a helper struct literal

Let's examine the exception to the addressability requirements:

As an exception to the addressability requirement, x [in the expression of &x] may also be a (possibly parenthesized) composite literal.

This means that taking the address of a composite literal, e.g. a struct literal is ok. If we do so, we will have the struct value allocated and a pointer obtained to it. But if so, another requirement will become available to us: "field selector of an addressable struct operand". So if the struct literal contains a field of type int64, we can also take the address of that field!

Let's see this option in action. We will use this wrapper struct type:

type intwrapper struct {
    x int64
}

And now we can do:

instance6 := SomeType{
    SomeField: &(&intwrapper{6}).x,
}

Note that this

&(&intwrapper{6}).x

means the following:

& ( (&intwrapper{6}).x )

But we can omit the "outer" parenthesis as the address operator & is applied to the result of the selector expression.

Also note that in the background the following will happen (this is also a valid syntax):

&(*(&intwrapper{6})).x

7) With helper anonymous struct literal

The principle is the same as with case #6, but we can also use an anonymous struct literal, so no helper/wrapper struct type definition needed:

instance7 := SomeType{
    SomeField: &(&struct{ x int64 }{7}).x,
}

Use a function which return an address of a int64 variable will solve the problem.

In the below code we use a function f which accepts integer and return a pointer value which holds the address of the integer. By using this method we can easily solve the above problem.

 type myStr struct {
        url *int64
    }

    func main() {

        f := func(s int64) *int64 {
            return &s
        }
        myStr{
            url: f(12345),
        }
    }

참고URL : https://stackoverflow.com/questions/30716354/how-do-i-do-a-literal-int64-in-go

반응형