Как преобразовать значение типа int в строку в Go?


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

s это «E», но я хочу «123»

Пожалуйста, скажите мне, как я могу получить «123».

А на Java я могу сделать так:

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

как я могу concatдве строки в го?


Второй вопрос (конкатенация строк) имеет ответ в другом месте, который охватывает эффективность.
RedGrittyBrick

Ответы:


772

Используйте функцию strconvпакета Itoa.

Например:

package main

import (
    "strconv"
    "fmt"
)

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

Вы можете объединить строки, просто используя +их или используя Joinфункцию stringsпакета.


97
Почему разработчики языка считают, что названия загадочных функций, таких как «Itoa», предпочтительнее, чем что-то более наглядное?
Люк

25
@luke это происходит из наследия C, где вся машина может иметь 256Кб памяти; удобство использования было принесено в жертву, чтобы соответствовать большей функциональности. Создатели Go глубоко укоренились в этом наследии и чувствуют себя вполне комфортно с этими именами.
Брайан,

117
Ставить историю выше доступности и легкости обучения - плохой дизайн ИМО. :(
Люк

32
@Luke Зависит от того, кто ваши целевые пользователи и насколько сильны соглашения. Некоторые пользовательские интерфейсы все еще имеют дискету в виде значка «Сохранить» :)
Nathron

65
для легкого запоминания имени ItoA - целое число в ASCII
Иван Араки

139
fmt.Sprintf("%v",value);

Если вы знаете конкретный тип значения, используйте соответствующий форматер, например, %dдляint

Больше информации - fmt


%dдля int - this
scniro

4
Я не рекомендовал бы это, поскольку это намного менее эффективно, чем другие методы преобразования, потому что он использует отражение.
Рикардо Соуза

49

Интересно отметить, что strconv.Itoaэто сокращение для

func FormatInt(i int64, base int) string

с основанием 10

Например:

strconv.Itoa(123)

эквивалентно

strconv.FormatInt(int64(123), 10)

undefined: strconv в strconv.Itoa
Фело Вильчес

1
@FeloVilches import "strconv"
kgthegreat

3
Интересно отметить, что вызов FormatInt () напрямую вместо Itoa () экономит 0,1 наносекунды в соответствии с
тестом

43

fmt.Sprintf, strconv.ItoaИ strconv.FormatIntбудет делать эту работу. Но Sprintfбудет использовать пакет reflect, и он выделит еще один объект, так что это не эффективный выбор.

введите описание изображения здесь



22

В этом случае оба strconvи fmt.Sprintfвыполняют одну и ту же работу, но с использованием функции strconvпакета Itoa- лучший выбор, потому что fmt.Sprintfвыделите еще один объект во время преобразования.

проверьте результат nenchmark обоих проверьте эталонный тест здесь: https://gist.github.com/evalphobia/caee1602969a640a4530

см., например, https://play.golang.org/p/hlaz_rMa0D .


1
@Boon В видимом влиянии на ваше приложение? Как всегда - это зависит. Другой объект означает, что нужно собрать еще один объект, помимо очевидного временного небольшого попадания в память. Если вы вызываете функцию с высокой скоростью, например, как часть какого-либо процесса сериализации, используемого всякий раз, когда сообщение откуда-то принимается, это может оказать значительное влияние. Поскольку fmt.Sprintfи strconv.iotaс точки зрения простоты использования они похожи, а приведенные выше данные показывают, что йота быстрее с меньшим влиянием GC, похоже, что iotaследует использовать в целом, когда требуется преобразовать одно целое число.
Эдвард

Мне кажется преждевременной оптимизацией думать так скоро. Лучше всего сначала написать читаемый код.
Благо

@Boon Они одинаково читабельны. Можно также использовать более быстрый. Кроме того, что сказать, что новый программист Golang не начинает с того, что делает много этих преобразований? Я опытный программист, пишу свой первый код Golang прямо сейчас и нахожусь в такой ситуации.
Судо


3

хорошо, большинство из них показали вам что-то хорошее. Позвольте мне дать вам это:

// 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 ""
    }
}

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)
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.