Golang中无法将MaybeString转换为String的解决方法

Golang中无法将MaybeString转换为String的解决方法 你好,

我来自Java技术栈,对Go语言完全是新手。我正在尝试使用sipParser库(GitHub - StefanKopieczek/gossip: SIP stack in Golang)来解析SipUri。 例如:sip:bob@192.168.6.236:5060,我想提取出bob。我使用ParseSipUri方法来解析它,如下所示:

uri, err := parser.ParseSipUri(fromNumber)
fmt.Println("Parsed From Number:", uri.User)

上面的代码成功打印出了bob,但我需要将uri.User(它是MaybeString类型,这是一个接口)转换为字符串。我尝试了许多不同的方法,但都没有成功。你能帮我找到转换的方法吗?

库中的SipUri结构如下:

type SipUri struct {
	// True if and only if the URI is a SIPS URI.
	IsEncrypted bool

	// The user part of the URI: the 'joe' in sip:joe@bloggs.com
	// This is a pointer, so that URIs without a user part can have 'nil'.
	User MaybeString
...
...
...
}
type MaybeString interface {
	implementsMaybeString()
}

更多关于Golang中无法将MaybeString转换为String的解决方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

有时查看测试代码可以告诉你一个类型应该如何被使用。我在测试中发现了这个 strMaybeStr 函数,其中 MaybeString 的使用方式如下:

func strMaybeStr(s base.MaybeString) string {
	switch s := s.(type) {
	case base.NoString:
		return "<none>"
	case base.String:
		return s.String()
	default:
		return "nil"
	}
}

所以看起来 MaybeString 可以是 nil,或者包含 NoStringString

更多关于Golang中无法将MaybeString转换为String的解决方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你好 @eaglesinblack

欢迎来到 Go 的世界!

我对接口及其用途感到有些困惑。我快速且简单地尝试实现了一个 Go 风格的版本,但我不确定它是否适合你的情况。

Playground 链接

package main

import (
	"fmt"
	"log"
)

// 这是一个结构体,以便我们可以定义一个 String() 方法。
type MaybeString struct {
	Name *string
}

// 实现 "Stringer" 接口。String() 方法应该返回其类型的字符串表示形式。
// 在这里,如果 Name 为 nil,String() 返回一个空字符串,否则返回 Name 的字符串形式。
func (ms *MaybeString) String() string {
	if ms == nil {
		return ""
	}
	return *(ms.Name)
}

type SipUri struct {
	IsEncrypted bool
	User        MaybeString
}

func ParseSipUri(n int) (SipUri, error) {
	return SipUri{false, MaybeString{Name: nil}}, nil
}

func main() {
	uri, err := ParseSipUri(23)
	if err != nil {
		log.Fatalf("Error parsing SIP URI")
	}
	fmt.Println("Parsed From Number:", uri.User)  // uri.User 有一个 String() 方法。Println() 可以正常工作。
}

思路如下:

  • MaybeString 实现了 Stringer 接口。这个接口允许任何自定义类型生成自身的字符串表示形式。fmt.PrintX() 系列函数能识别 String() 方法。
  • String 方法处理了字符串可能为 nil 的情况,如果 Namenil,则返回一个空字符串。

在Go中,MaybeString是一个接口,你需要通过类型断言或类型开关来获取具体的字符串值。查看gossip库的源码,MaybeString接口有两个实现:StringNullString

以下是转换方法:

package main

import (
    "fmt"
    "github.com/StefanKopieczek/gossip/sip/parser"
)

func main() {
    fromNumber := "sip:bob@192.168.6.236:5060"
    uri, err := parser.ParseSipUri(fromNumber)
    if err != nil {
        panic(err)
    }

    // 方法1:类型断言
    if userStr, ok := uri.User.(parser.String); ok {
        fmt.Println("User:", string(userStr))
    } else if uri.User == nil {
        fmt.Println("User is nil")
    } else {
        fmt.Println("User is not a string")
    }

    // 方法2:类型开关
    switch user := uri.User.(type) {
    case parser.String:
        fmt.Println("User (switch):", string(user))
    case parser.NullString:
        fmt.Println("User is null string")
    case nil:
        fmt.Println("User is nil")
    default:
        fmt.Println("Unknown user type")
    }

    // 方法3:使用库提供的String()方法
    // 查看源码发现String类型实现了String()方法
    if userStr, ok := uri.User.(fmt.Stringer); ok {
        fmt.Println("User (Stringer):", userStr.String())
    }
}

如果需要频繁使用,可以创建一个辅助函数:

func maybeStringToString(m parser.MaybeString) string {
    switch v := m.(type) {
    case parser.String:
        return string(v)
    case parser.NullString:
        return ""
    default:
        return ""
    }
}

// 使用示例
user := maybeStringToString(uri.User)
fmt.Println("User:", user)

关键点:

  1. parser.Stringstring的类型别名,可以直接转换为string
  2. parser.NullString表示空字符串情况
  3. 使用类型断言时总是检查ok
  4. 注意处理nil情况,因为User字段是指针

对于你的具体用例,提取用户名的完整代码:

uri, err := parser.ParseSipUri("sip:bob@192.168.6.236:5060")
if err != nil {
    // 处理错误
}

var username string
if userStr, ok := uri.User.(parser.String); ok {
    username = string(userStr)
}
fmt.Println("Username:", username) // 输出: bob
回到顶部