Как преобразовать переменную типа **T
в *unsafe.Pointer
?
Пример ниже даст ошибку компиляции:
не может преобразовать &ptr (тип **s) в тип *unsafe.Pointer
package main
import (
"sync/atomic"
"unsafe"
)
type s struct {
value int
}
func main(){
var ptr *s
a := &s{42}
old := ptr
atomic.CompareAndSwapPointer(
(*unsafe.Pointer)(&ptr), // &unsafe.Pointer(ptr)
unsafe.Pointer(old),
unsafe.Pointer(a))
}
Если я переключу (*unsafe.Pointer)(&ptr)
на &unsafe.Pointer(ptr)
, я получу эту ошибку компиляции:
не может получить адрес unsafe.Pointer(ptr)
Пс. Я решил сделать пример с sync/atomic
, потому что это одна из ситуаций, когда вам действительно нужно выполнить такое преобразование.
Изменить
Одним из неправильных решений было бы использование временной переменной:
up := unsafe.Pointer(ptr)
atomic.CompareAndSwapPointer(&up, ...
Во время компиляции CAS будет заменять только то, что хранится в up
, а не в ptr
. Как указал zeebo@#go-nuts, это не желаемый результат.