紧急:接口转换:接口{}是** string,不是string

How to convert double pointer string to string?

In this example we can directly pass string argument. But I have double pointer string to string requirement in my app.

package main

import (
    "fmt"
)

func main() {
    s := "ss"
    a := &s
    Modify(&a)
}

func Modify(s interface{}) {
    fmt.Println(s)

}

Playground: https://play.golang.org/p/d4hrG9LzLNO

You require to assert **string to get underlying value wrapped around interface{}. And then dereference the value of string using double pointer.

package main

import (
    "fmt"
)

func main() {
    s := "ss"
    a := &s
    Modify(&a)
}

func Modify(s interface{}) {
     fmt.Println(**s.(**string))
}

Playground

If you can't avoid having a **string, this is how you can handle it: assert **string from the interface{} value (since this is what it contains), and then dereference the pointer which gives you *string which you again can dereference which gives you the string value.

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"
}

Output (try it on the Go Playground):

Before a: ss
After a: modified
After s: modified

But know that if you already have a variable of *string type (which is a), you don't need to take and pass its address, you can pass it as-is (a *string value):

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"
}

Output again will be (try it on the Go Playground):

Before a: ss
After a: modified
After s: modified

Note that in both cases the value pointed by a changed to "modified", but the value of s also changed. This is because inside Modify() we modified the pointed-pointed value. If you only want a to change (more specifically the value pointed by a) but you don't want to change s, then inside Modify() you should only modify the value pointed by sp, which will be the variable a, but not the pointed-pointed value (which is s). In order to only change the pointed value, you have to assign a value of type *string to it:

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
}

This time the output will be (try it on the Go Playground):

Before a: ss
After a: modified
After s: ss

As you can see, Modify() modified the value pointed by a, but s remained unchanged.