【问题标题】:panic: interface conversion: interface {} is **string, not string恐慌:接口转换:接口{}是**字符串,而不是字符串
【发布时间】:2018-04-14 08:03:17
【问题描述】:

如何将双指针字符串转成字符串?

在这个例子中,我们可以直接传递字符串参数。但是我的应用中有指向字符串要求的双指针字符串。

package main

import (
    "fmt"
)

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

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

}

游乐场:https://play.golang.org/p/d4hrG9LzLNO

【问题讨论】:

    标签: string pointers go interface


    【解决方案1】:

    如果您无法避免拥有**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 保持不变。

    【讨论】:

      【解决方案2】:

      您需要断言**string 以获取围绕interface{} 的底层价值。然后使用double 指针取消引用字符串的值。

      package main
      
      import (
          "fmt"
      )
      
      func main() {
          s := "ss"
          a := &s
          Modify(&a)
      }
      
      func Modify(s interface{}) {
           fmt.Println(**s.(**string))
      }
      

      Playground

      【讨论】:

      • 如果我不知道Modify 方法上的变量s 的类型是什么,我该怎么做?到现在为止,我大约 4 小时前被卡住了,
      猜你喜欢
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      • 2015-02-25
      • 1970-01-01
      • 2012-10-11
      • 2013-02-21
      • 2018-01-15
      • 1970-01-01
      相关资源
      最近更新 更多