Идиоматический способ приведения строки к любому другому примитивному типу - PullRequest
0 голосов
/ 07 января 2019

Я пытаюсь создать функцию, которая может приводить данную строку к заданному типу отражения.

Я использую пакет 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, но как новичок в разработке, я не уверен, что есть лучший подход.

Спасибо за вашу помощь.

1 Ответ

0 голосов
/ 07 января 2019

Оператор "большого переключателя", которого вы хотите избежать, уже записан в стандартной библиотеке. Используйте пакет 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 error). Вторая строка содержит проанализированные значения i и f.

Для получения дополнительных опций читайте: Преобразовать строку в целочисленный тип в Go?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...