Formatowanie tekstu w Go lepiej niż FMT

Patrząc na tytuł artykułu, powinniśmy wyjaśnić, co rozumiemy przez lepsze i czym jest formatowanie tekstu. Zacznijmy od tego pierwszego. Formatowanie tekstu jest ważną częścią programowania; przygotowany tekst jest używany w następujących zadaniach:

  • Opis/wynik niektórych operacji
  • Szczegółowy dziennik
  • Jako zapytanie dotyczące wyboru danych w innych systemach
  • I w wielu innych dziedzinach. Lepiej oznacza, że sf (wissance.StringFormatter) posiada funkcje, które fmt nie ma (proszę zapoznać się z Rozdziałem 1, aby zobaczyć nasze podejście do formatowania tekstu).

1. Co może zrobić sf aka Wissance.stringformatter

W naszym wcześniejszym artykule, pisaliśmy o sf wygoda (wygoda jest rzeczą, która jest subiektywna dla ludzi; tutaj mam na myśli wygodę opartą na moim własnym tle). Krótko mówiąc, wygodniej jest formatować tekst w ten sposób:

userNews = stringFormatter.Format("Hi \"{0}\", see latest news: {1}", "john doe", "1. You won 1M$ in a lottery, please give us your VISA/MS card data to receive money.")

Zamiast:

userNews = fmt.Sprintf("Hi \"%s\", see latest news: %s", "john doe", "1. You won 1M$ in a lottery, please give us your VISA/MS card data to receive money.")

Do czasu wersja 1.2.0 sf nie była w stanie dokonać bardziej precyzyjnego formatowania argumentów (tj. użyć innej notacji liczbowej: bin, hex), Począwszy od wersji 1.2.0 mogliśmy zrobić prawie to wszystko fmt wspiera:

  1. Formatowanie numeru pojemnika:
    • {0:B}, 15 wyjść -> 1111
    • {0:B8}, 15 wyjść -> 00001111
  2. Formatowanie liczb szesnastkowych
    • {0:X}, 250 wyjść -> fa
    • {0:X4}, 250 wyjść -> 00fa
  3. Formatowanie numeru października
  4. Formatowanie liczb zmiennoprzecinkowych
    • {0:E2}, 191.0478 wyjść -> 1.91e+02
    • {0:F}, 10.4567890 outputs -> 10.456789
    • {0:F4}, 10.4567890 outputs -> 10.4568
    • {0:F8}, 10.4567890 outputs -> 10.45678900
  5. Wydajność procentowa
    • {0:P100}, 12 wyjść -> 12%

sf ma dwie metody formatowania ciągów znaków: Format i FormatComplex. Ten ostatni umożliwia również przekazywanie formatowania argumentów, jak w przypadku Format method.

Rozważmy minimalny przykład:

  1. Powinniśmy zbudować tekst przy użyciu następującego formatu "Today tempearture is {temp}, humidity is {hum} gdzie {temp} oraz {hum} proszę zastąpić rzeczywistymi wartościami czujnika.
  2. Chcielibyśmy określić {temp} oraz {hum} wyjściowe, tj, {temp} powinien mieć cztery cyfry po kropce, a {hum} muszą być wyświetlane w procentach. Po przeanalizowaniu tych wymagań zmodyfikowaliśmy nasz szablon w następujący sposób: "Today tempearture is {temp:F4}, humidity is {hum:P100}".
  3. Podanie 12.3456 oraz 60 w ten sposób:
   sf.FormatComplex("Today tempearture is {temp:F4}, humidity is {hum:P100}", map[string]any {"temp":12.3456, "hum":60})

Więcej przykładów można znaleźć w FormatComplex test jednostkowy, proszę zobaczyć w repozytorium i poniżej:

func TestFormatComplexWithArgFormatting(t *testing.T) {    for name, test := range map[string]struct {        template string        args     map[string]any        expected string    }{        "numeric_test_1": {            template: "This is the text with an only number formatting: scientific - {mass} / {mass : e2}",            args:     map[string]any{"mass": 191.0784},            expected: "This is the text with an only number formatting: scientific - 191.0784 / 1.91e+02",        },        "numeric_test_2": {            template: "This is the text with an only number formatting: binary - {bin:B} / {bin : B8}, hexadecimal - {hex:X} / {hex : X4}",            args:     map[string]any{"bin": 15, "hex": 250},            expected: "This is the text with an only number formatting: binary - 1111 / 00001111, hexadecimal - fa / 00fa",        },        "numeric_test_3": {            template: "This is the text with an only number formatting: decimal - {float:F} / {float : F4} / {float:F8}",            args:     map[string]any{"float": 10.5467890},            expected: "This is the text with an only number formatting: decimal - 10.546789 / 10.5468 / 10.54678900",        },    } {        t.Run(name, func(t *testing.T) {            assert.Equal(t, test.expected, stringFormatter.FormatComplex(test.template, test.args))        })    }
}

Jest jasne, że mamy wygodne (dla osób z C#, Python tło) biblioteka do formatowania tekstu. Ale mamy jeszcze jedną zaletę: wydajność, sf przyspiesza formatowanie niż fmt**.

2. Korzyści z wydajności

Jest jeszcze jedna ważna rzecz, która może wyróżnić sf bibliotekę: ma ona postępy w wydajności, zarówno w przypadkach formatowania ze specyfikacją formatu argumentu, jak i bez niej. Ale FormatComplex jest dwa razy szybsza niż fmtProszę zobaczyć obrazek poniżej z wynikami:

porównanie wydajności sf vs fmt

3. Wnioski

Dziś możemy powiedzieć, że istnieje jeszcze jedno narzędzie/lib do formatowania tekstu z wszystkimi fmt a ta biblioteka przetwarza tekst szybciej, co w niektórych przypadkach może być ważne. Proszę dać nam gwiazdkę na GitHub i subskrybować.