如果您无法避免拥有**string,您可以通过以下方式处理它:从interface{} 值断言**string(因为这是它包含的内容),然后取消引用给您的指针*string 您可以再次取消引用,从而为您提供 string 值。
func main() {
s := "ss"
a := &s
fmt.Println("Before a:", *a)
Modify(&a)
fmt.Println("After a:", *a)
fmt.Println("After s:", s)
}
func Modify(s interface{}) {
sp := s.(**string)
**sp = "modified"
}
输出(在Go Playground 上试试):
Before a: ss
After a: modified
After s: modified
但是要知道,如果你已经有一个*string类型的变量(也就是a),你不需要取并传递它的地址,你可以按原样传递它(一个*string值):
func main() {
s := "ss"
a := &s
fmt.Println("Before a:", *a)
Modify(a)
fmt.Println("After a:", *a)
fmt.Println("After s:", s)
}
func Modify(s interface{}) {
sp := s.(*string)
*sp = "modified"
}
再次输出将是(在Go Playground 上尝试):
Before a: ss
After a: modified
After s: modified
注意,在这两种情况下a 指向的值都更改为"modified",但s 的值也发生了更改。这是因为在 Modify() 内部我们修改了 pointed-pointed 值。如果您只想更改a(更具体地说是a 指向的值)但不想更改s,那么在Modify() 内部您应该只修改sp 指向的值,即将是变量a,但不是指向值(即s)。为了只更改指向的值,您必须为其分配一个 *string 类型的值:
func main() {
s := "ss"
a := &s
fmt.Println("Before a:", *a)
Modify(&a)
fmt.Println("After a:", *a)
fmt.Println("After s:", s)
}
func Modify(s interface{}) {
sp := s.(**string)
newValue := "modified"
*sp = &newValue
}
这次的输出将是(在Go Playground上试试):
Before a: ss
After a: modified
After s: ss
如您所见,Modify() 修改了a 指向的值,但s 保持不变。