【问题标题】:Idiomatic way to cast a string to any other primitive type将字符串转换为任何其他原始类型的惯用方式
【发布时间】:2019-06-02 03:49:47
【问题描述】:

我正在尝试创建一个可以将给定字符串转换为给定反射类型的函数。

我正在使用cast 包:

package main

import (
    "fmt"
    "reflect"
    "strings"

    "github.com/spf13/cast"
)

type functions struct{}

func (f functions) Float64(v string) float64 {
    return cast.ToFloat64(v)
}

func toTarget(v string, target reflect.Kind) interface{} {
    n := strings.Title(fmt.Sprintf("%s", target))
    method := reflect.ValueOf(functions{}).MethodByName(n)
    // Call.
    return method.Call([]reflect.Value{reflect.ValueOf(v)})[0].Interface()
}

func main() {
    originalValue := "10.0"
    floatingValue := toTarget(originalValue, reflect.Float64)

    fmt.Println(floatingValue)
}

在上面的示例中,我保持简单(它仅适用于字符串 -> float64 转换),但在我的代码中,它也适用于所有其他原语。

我更喜欢使用这个解决方案而不是巨大而丑陋的 switch 语句,但作为一个新的 go 开发人员,我不确定是否有更好的方法。

感谢您的帮助。

【问题讨论】:

  • Go 中根本没有类型转换,无论是惯用的还是其他的。仅类型转换。
  • 为什么不直接使用n, err := fmt.Sscan("someString", &variable)?这将处理您需要的大多数类型。剩下的,你无论如何都需要自定义解析......
  • 嘿@icza,你能提供一个使用fmt.Sscan的工作示例吗?我正在尝试,但它一直返回错误expected integer
  • 为什么投反对票?这个问题是有效的,并提供了我想要完成的事情。
  • @ubaxibuna 使用fmt.Sscan(),您必须传递变量的地址,而不是reflect.Kind,例如var i int; fmt.Sscan("12", &i)

标签: string parsing go types


【解决方案1】:

您要避免的“大开关”语句已经写在标准库中。使用fmt 包轻松解析字符串中的原始值,特别是fmt.Sscan()fmt.Sscanf() 函数。

fmt.Sscan() 需要一个字符串值来解析出某些内容,以及将解析后的值放入的变量的地址。指向变量的类型也决定了从字符串中解析出什么以及如何解析。 fmt.Sscan() 将返回成功解析值的数量,以及一个可选错误(如果出现问题)。

一个简单的例子:

var i int
if _, err := fmt.Sscan("12", &i); err != nil {
    fmt.Println("Error:", err)
}
fmt.Println(i)

var f float32
if _, err := fmt.Sscan("12.2", &f); err != nil {
    fmt.Println("Error:", err)
}
fmt.Println(f)

输出(在Go Playground 上试试):

12
12.2

另外请注意,您可以使用fmt.Sscan() 一步解析多个值,例如:

var i int
var f float32

fmt.Println(fmt.Sscan("12 12.2", &i, &f))
fmt.Println(i, f)

这将打印(在Go Playground 上尝试):

2 <nil>
12 12.2

第一行包含fmt.Sscan()的返回值:告诉它解析了2个值,并且没有返回错误(nil错误)。第二行包含if的解析值。

更多选项,请阅读:Convert string to integer type in Go?

【讨论】:

  • 完美!非常感谢icza!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-17
  • 2022-11-25
  • 1970-01-01
相关资源
最近更新 更多