我有一个带*int64
字段的结构类型.
type SomeType struct {
SomeField *int64
}
Run Code Online (Sandbox Code Playgroud)
在我的代码中的某个时刻,我想声明一个这样的文字(比如,当我知道所述值应为0,或者指向0时,你知道我的意思)
instance := SomeType{
SomeField: &0,
}
Run Code Online (Sandbox Code Playgroud)
...除了这不起作用
./main.go:xx: cannot use &0 (type *int) as type *int64 in field value
Run Code Online (Sandbox Code Playgroud)
所以我试试这个
instance := SomeType{
SomeField: &int64(0),
}
Run Code Online (Sandbox Code Playgroud)
......但这也行不通
./main.go:xx: cannot take the address of int64(0)
Run Code Online (Sandbox Code Playgroud)
我该怎么做呢?我能想出的唯一解决方案是使用占位符变量
var placeholder int64
placeholder = 0
instance := SomeType{
SomeField: &placeholder,
}
Run Code Online (Sandbox Code Playgroud)
注意:当它是*int而不是a时,编辑:不,不.为此表示歉意.&0
语法工作正常*int64
.
编辑:
显然,我的问题含糊不清.我正在寻找一种方法来说明一个*int64
.这可以在构造函数中使用,或者用于表示文字结构值,或者甚至作为其他函数的参数.但帮助函数或使用不同的类型不是我正在寻找的解决方案.
我只需要一个指向time.Time的指针,所以下面的代码似乎无效:
./c.go:5:不能取时间地址.现在()
我只是想知道为什么?有没有办法做到这一点,除了先对变量赋值并获取变量的指针?
package main
import "time"
func main() {
_ = &time.Now()
}
Run Code Online (Sandbox Code Playgroud) 这编译和工作:
diff := projected.Minus(c.Origin)
dir := diff.Normalize()
Run Code Online (Sandbox Code Playgroud)
这不会(产生标题中的错误):
dir := projected.Minus(c.Origin).Normalize()
Run Code Online (Sandbox Code Playgroud)
有人可以帮我理解为什么吗?(学习Go)
以下是这些方法:
// Minus subtracts another vector from this one
func (a *Vector3) Minus(b Vector3) Vector3 {
return Vector3{a.X - b.X, a.Y - b.Y, a.Z - b.Z}
}
// Normalize makes the vector of length 1
func (a *Vector3) Normalize() Vector3 {
d := a.Length()
return Vector3{a.X / d, a.Y / d, a.Z / d}
}
Run Code Online (Sandbox Code Playgroud) Go FAQ 回答了一个关于方法中按值与按指针接收器定义选择的问题。该答案中的陈述之一是:
如果该类型的某些方法必须有指针接收器,其余的也应该如此,因此无论如何使用该类型,方法集都是一致的。
这意味着,如果我对一个数据类型有一些改变数据的方法,因此需要按指针接收器,我应该对为该数据类型定义的所有方法使用按指针接收器。
另一方面,"fmt"
包通过 value调用接口中String()
定义的方法。如果用接收器按指针定义方法,则当关联的数据类型作为参数提供给(或其他格式化方法)时,将不会调用该方法。这让人们别无选择,只能使用接收器按值实现该方法。Stringer
String()
fmt.Println
fmt
String()
正如常见问题解答所建议的那样,在满足接口fmt
要求的同时,如何与按值与按指针的选择保持一致Stringer
?
编辑:
为了强调我提到的问题的本质,考虑一个数据类型,其中包含一组用接收者按值定义的方法(包括 String())。然后一个人希望添加一个额外的方法来改变该数据类型 - 所以他用接收者按指针定义它,并且(为了保持一致,每个常见问题解答)他还更新了该数据类型的所有其他方法以供使用- 指针接收器。此更改对使用此数据类型方法的任何代码的影响为零 - 但用于调用fmt
格式化函数(现在需要将指针传递给变量而不是其值,就像更改之前一样)。因此,一致性要求仅在fmt
. 需要调整提供变量的方式fmt.Println
(或类似功能)基于接收器类型打破了轻松重构一个包的能力。
我见过几个不同的例子sync.WaitGroup
实施例1
var wg sync.WaitGroup
wg.Add(1)
go doStuff(&wg)
wg.Wait()
Run Code Online (Sandbox Code Playgroud)
实施例2
wg := new(sync.WaitGroup)
wg.Add(1)
go doStuff(wg)
wg.Wait()
Run Code Online (Sandbox Code Playgroud)
区别实际上在于sync.WaitGroup
初始化
方式var
与new
如果使用该var
选项,它必须作为&wg
指向 goroutine 的指针传递,但如果我使用该new
选项,我可以将其发送为wg
这两个例子有什么区别?上面这2个哪一个是正确的?在某些情况下,是否优先选择其中一种?
我正在编写一个创建多个 s 的程序,那么使用orsync.WaitGroup
是否重要?new
var
根据对这个问题的回应
有关接收器的指针与值的规则是可以在指针和值上调用值方法,但只能在指针上调用指针方法
但实际上我可以对非指针值执行指针方法:
package main
import "fmt"
type car struct {
wheels int
}
func (c *car) fourWheels() {
c.wheels = 4
}
func main() {
var c = car{}
fmt.Println("Wheels:", c.wheels)
c.fourWheels()
// Here i can execute pointer method on non pointer value
fmt.Println("Wheels:", c.wheels)
}
Run Code Online (Sandbox Code Playgroud)
那么,这里有什么问题?这是一个新功能吗?或者对问题的回答是错误的?
我有 Go 函数,并且我想取消引用要存储在指针中的第一个值。
例如:
func foo() (int64, error) {...}
var A *int64
var err error
A, err = &foo()
Run Code Online (Sandbox Code Playgroud)
这是可能的,还是我必须复制(在我的情况下非常大)返回值?
来自 C#,这让我感到困惑。在 Go 中,如果我有
type Employee struct {
ID int
Salary int
}
Run Code Online (Sandbox Code Playgroud)
那我就可以了
var tom Employee
tom.Salary = 100
Run Code Online (Sandbox Code Playgroud)
到目前为止,一切都很好。那么如果我有一个功能
func employeeByID(id int) Employee {
// do something and return an employee
}
Run Code Online (Sandbox Code Playgroud)
那为什么不编译呢?
employeeByID(10).Salary = 100
Run Code Online (Sandbox Code Playgroud)
此外,这似乎编译得很好:
andrew := employeeByID(10)
andrew.Salary = 100
Run Code Online (Sandbox Code Playgroud) 在Go中,如何将函数调用返回的值赋给指针?
考虑这个例子,注意time.Now()
返回一个time.Time
值(而不是指针):
package main
import (
"fmt"
"time"
)
type foo struct {
t *time.Time
}
func main() {
var f foo
f.t = time.Now() // Fail line 15
f.t = &time.Now() // Fail line 17
tmp := time.Now() // Workaround
f.t = &tmp
fmt.Println(f.t)
}
Run Code Online (Sandbox Code Playgroud)
这两个都失败了:
$ go build
# _/home/jreinhart/tmp/go_ptr_assign
./test.go:15: cannot use time.Now() (type time.Time) as type *time.Time in assignment
./test.go:17: cannot take the address of time.Now()
Run Code Online (Sandbox Code Playgroud)
真的需要局部变量吗?这不是一个不必要的副本吗?
在下一个代码中,第一个代码Println
在构建时失败并出现错误slice of unaddressable value
。其余的线条都很好。
package main
import "fmt"
func getSlice() [0]int {
return [...]int{}
}
func getString() string {
return "hola"
}
func main() {
fmt.Println(getSlice()[:]) // Error: slice of unaddressable value
var a = getSlice()
fmt.Println(a[:])
fmt.Println(getString()[:])
var b = getString()
fmt.Println(b[:])
}
Run Code Online (Sandbox Code Playgroud)
如果第一个Println
被评论它就有效。
试试看
这是为什么?我在这里缺少什么?
我想找出原因
x:= odsMap[segRef]
x.GetValue("@OriginDestinationKey")
Run Code Online (Sandbox Code Playgroud)
可以,但是不能:
odsMap[segRef].GetValue("@OriginDestinationKey")
Run Code Online (Sandbox Code Playgroud)
?
最后一个代码段显示以下错误:
cannot call pointer method on odsMap[segRef]go
cannot take the address of odsMap[segRef]
Run Code Online (Sandbox Code Playgroud)
这些错误发生在编译时(而不是运行时)。所以,我的主要问题是为什么我需要一个中间变量x
来访问该函数?
关于变量的类型odsMap
是map[string]
XMLElement并且segRef
是字符串。
谢谢。
go ×11
pointers ×8
methods ×4
struct ×2
call ×1
concurrency ×1
dereference ×1
dictionary ×1
interface ×1
literals ×1
slice ×1
string ×1