Jak przekonwertować wartość int na ciąg w Go?

486
i := 123
s := string(i) 

s to „E”, ale to, czego chcę, to „123”

Powiedz mi, jak mogę uzyskać „123”.

A w Javie mogę zrobić w ten sposób:

String s = "ab" + "c"  // s is "abc"

Jak mogę concatdwa ciągi w Go?

hardPass
źródło
Drugie pytanie (konkatenacja łańcuchów) zawiera odpowiedź, która dotyczy wydajności.
RedGrittyBrick

Odpowiedzi:

772

Użyj funkcji strconvpakietu Itoa.

Na przykład:

package main

import (
    "strconv"
    "fmt"
)

func main() {
    t := strconv.Itoa(123)
    fmt.Println(t)
}

Możesz konkatować łańcuchy, po prostu je +pisząc, lub używając Joinfunkcji stringspakietu.

Klaus Byskov Pedersen
źródło
97
Dlaczego projektanci języków uważali, że nazwy funkcji tajemniczych, takich jak „Itoa”, są lepsze niż coś, co może być nieco bardziej opisowe?
Łukasz
25
@luke pochodzi z dziedzictwa C, gdzie cała maszyna może mieć pamięć 256 KB; poświęcono użyteczność, aby zmieścić większą funkcjonalność. Twórcy Go są głęboko osadzeni w tym dziedzictwie i czują się całkowicie dobrze z tymi nazwami.
Bryan
117
Stawianie historii ponad dostępnością i łatwością uczenia się jest złym projektem IMO. :(
Luke
32
@Luke Zależy od tego, kim są Twoi użytkownicy docelowi i jak silna jest konwencja. Niektóre interfejsy użytkownika nadal mają dyskietkę jako ikonę Zapisz :)
Nathron
65
dla łatwego zapamiętywania nazwy ItoA - liczba całkowita do ASCII
Ivan Aracki
139
fmt.Sprintf("%v",value);

Jeśli znasz konkretny typ wartości, użyj odpowiedniego formatyzatora, na przykład %ddlaint

Więcej informacji - fmt

Jasmeet Singh
źródło
%ddla int - this
scniro
4
Nie poleciłbym tego, ponieważ jest to znacznie mniej wydajne niż inne metody konwersji, ponieważ wykorzystuje odbicie.
Ricardo Souza
49

Interesujące jest to, aby pamiętać, że strconv.Itoajest skrótem dla

func FormatInt(i int64, base int) string

z podstawą 10

Na przykład:

strconv.Itoa(123)

jest równa

strconv.FormatInt(int64(123), 10)
kgthegreat
źródło
undefined: strconv w strconv.Itoa
Felo Vilches
1
@FeloVilches import "strconv"
kgthegreat
3
Interesujące jest to, że wywołanie FormatInt () bezpośrednio zamiast Itoa () pozwala zaoszczędzić 0,1 nanosekundy zgodnie z testem na stackoverflow.com/a/38077508/968244
isapir
43

fmt.Sprintf, strconv.ItoaI strconv.FormatIntbędzie wykonać zadanie. Ale Sprintfużyje pakietu reflecti przydzieli jeszcze jeden obiekt, więc nie jest to skuteczny wybór.

wprowadź opis zdjęcia tutaj

Bryce
źródło
22

W tym przypadku oba strconvi fmt.Sprintfwykonują tę samą pracę, ale użycie funkcji strconvpakietu Itoajest najlepszym wyborem, ponieważ fmt.Sprintfprzy konwersji przydziel jeszcze jeden obiekt.

sprawdź wynik nenchmark obu sprawdź test tutaj: https://gist.github.com/evalphobia/caee1602969a640a4530

patrz na przykład https://play.golang.org/p/hlaz_rMa0D .

Manigandand
źródło
1
@Boon W widoczny sposób wpływa na Twoją aplikację? Jak zawsze - to zależy. Kolejny obiekt oznacza, że ​​jeszcze jeden obiekt, poza oczywistym tymczasowym trafieniem małej pamięci, musi zostać wyrzucony. Jeśli wywołujesz tę funkcję z dużą szybkością, na przykład jako część procesu serializacji stosowanego za każdym razem, gdy wiadomość jest odbierana skądś, może to mieć znaczący wpływ. Ponieważ fmt.Sprintfi strconv.iotasą podobne pod względem łatwości użycia, a powyższe dane pokazują, że jota jest szybsza przy mniejszym wpływie GC, wydaje się, że iotanależy ją stosować ogólnie, gdy jedna liczba całkowita wymaga konwersji.
Edward
Wydaje mi się, że przedwczesna optymalizacja tak szybko myśli na tym poziomie. Najlepiej jest najpierw napisać czytelny kod.
Boon
@Boon Są one równie czytelne. Równie dobrze można użyć szybszego. A co powiedzieć, że nowy programista Golang nie zaczyna od czegoś, co robi wiele z tych konwersji? Jestem doświadczonym programistą piszącym teraz mój pierwszy kod Golang i jestem w takiej sytuacji.
sudo
9

Konwertowanie int64:

n := int64(32)
str := strconv.FormatInt(n, 10)

fmt.Println(str)
// Prints "32"
Cae Vecchi
źródło
3

ok, większość z nich pokazała ci coś dobrego. Dam ci to:

// ToString Change arg to string
func ToString(arg interface{}, timeFormat ...string) string {
    if len(timeFormat) > 1 {
        log.SetFlags(log.Llongfile | log.LstdFlags)
        log.Println(errors.New(fmt.Sprintf("timeFormat's length should be one")))
    }
    var tmp = reflect.Indirect(reflect.ValueOf(arg)).Interface()
    switch v := tmp.(type) {
    case int:
        return strconv.Itoa(v)
    case int8:
        return strconv.FormatInt(int64(v), 10)
    case int16:
        return strconv.FormatInt(int64(v), 10)
    case int32:
        return strconv.FormatInt(int64(v), 10)
    case int64:
        return strconv.FormatInt(v, 10)
    case string:
        return v
    case float32:
        return strconv.FormatFloat(float64(v), 'f', -1, 32)
    case float64:
        return strconv.FormatFloat(v, 'f', -1, 64)
    case time.Time:
        if len(timeFormat) == 1 {
            return v.Format(timeFormat[0])
        }
        return v.Format("2006-01-02 15:04:05")
    case jsoncrack.Time:
        if len(timeFormat) == 1 {
            return v.Time().Format(timeFormat[0])
        }
        return v.Time().Format("2006-01-02 15:04:05")
    case fmt.Stringer:
        return v.String()
    case reflect.Value:
        return ToString(v.Interface(), timeFormat...)
    default:
        return ""
    }
}
fwhez
źródło
0
package main

import (
    "fmt" 
    "strconv"
)

func main(){
//First question: how to get int string?

    intValue := 123
    // keeping it in separate variable : 
    strValue := strconv.Itoa(intValue) 
    fmt.Println(strValue)

//Second question: how to concat two strings?

    firstStr := "ab"
    secondStr := "c"
    s := firstStr + secondStr
    fmt.Println(s)
}
Sagiruddin Mondal
źródło