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

s is 'E', but what I want is "123"

Please tell me how can I get "123".

And in Java, I can do in this way:

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

how can I concat two strings in Go?

030
  • 10,842
  • 12
  • 78
  • 123
hardPass
  • 19,033
  • 19
  • 40
  • 42
  • The second question (string concatenation) has [an answer elsewhere](https://stackoverflow.com/q/1760757/477035) that covers efficiency. – RedGrittyBrick Aug 07 '19 at 15:48
  • `strconv.Itoa(i)` (int to ASCII) to set an int to a string. See https://stackoverflow.com/a/62737936/12817546. `strconv.Atoi(s)` (ASCII to int) to set a string to an int. See https://stackoverflow.com/a/62740786/12817546. –  Jul 09 '20 at 08:56

10 Answers10

1159

Use the strconv package's Itoa function.

For example:

package main

import (
    "strconv"
    "fmt"
)

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

You can concat strings simply by +'ing them, or by using the Join function of the strings package.

Klaus Byskov Pedersen
  • 117,245
  • 29
  • 183
  • 222
  • 4
    If you have a lot of string concatenations to do (for example to build a long string) and want your code to be faster and with less allocations, you should consider using bytes.Buffer too (it's a kind of more generic version of Java's StringBuilder). – Denys Séguret Apr 11 '12 at 15:36
  • 236
    Why did the language designers think that cryptic functions names like "Itoa" were preferable to something that might be a little more descriptive? – Luke Jul 17 '16 at 20:27
  • 58
    @luke it comes from the C heritage where the entire machine might have 256K memory; usability was sacrificed to fit more functionality in. The creators of Go are all deeply embedded in that heritage and feel entirely comfortable with these names. – Bryan Sep 29 '16 at 10:15
  • 228
    Putting history above accessibility and ease of learning is bad design IMO. :( – Luke Sep 29 '16 at 14:00
  • 60
    @Luke Depends on who your target users are and how strong the convention is. Some UIs still have a floppy disk as the Save icon :) – Nathron Nov 14 '16 at 23:43
  • 4
    @Luke I hate that you're being so logical and right about this. These hints of C-like crypticness are part of Go's sex appeal! – Angad Mar 15 '17 at 15:42
  • 163
    for easy remembering name **ItoA** - **Integer to ASCII** – Ivan Aracki Feb 22 '18 at 11:51
  • 3
    `bytes.Buffer` will bite your fingers if you continue using it. Use `strings.Builder` instead. – Erikas Dec 21 '18 at 15:54
  • @IvanAracki easy to remember because that's what it stands for – JoelFan Jan 29 '19 at 19:16
  • 3
    @Bryan Except then they make tons of random changes to make it not like C, such as putting the type after the name when you declare a variable. – sudo Feb 20 '19 at 01:32
  • 1
    @sudo read [this blog post](https://blog.golang.org/gos-declaration-syntax) to see why the type after the name is a better design – Christopher Poile Mar 13 '19 at 14:30
  • 1
    @IvanAracki very helpful. I quoted you in https://stackoverflow.com/a/62737936/12817546. I guess Atoi is "ASCII to integer". –  Jul 07 '20 at 08:06
  • 3
    `Itoa` does only `return FormatInt(int64(i), 10)`. IMO the `FormatInt` function is neither cryptic nor bad design. And I really like how the shortcut here, i.e. `Itoa` is a nod to the same method in C. – kapad Aug 20 '20 at 21:41
  • 5
    I love how this comment section has decided it's the place to determine the value of Go's roots and design decisions. – Kyle Sep 16 '20 at 00:47
  • Iota probably stands for (I)nteger (to) (a)scii. So it is not cryptic as we might think. – Sam Oz May 13 '22 at 13:21
  • 1
    @luke It's not strictly part of the language. It's a library and you can change that if you really want to. I like 'from' more than 'to' because reading left to right I see the LHS being the type I get and the L value and the RHS being what I provide in the function e.g. aString := StringFromInteger(1234) – tristram May 19 '22 at 13:19
197
fmt.Sprintf("%v",value);

If you know the specific type of value use the corresponding formatter for example %d for int

More info - fmt

Jasmeet Singh
  • 2,347
  • 1
  • 11
  • 10
91

fmt.Sprintf, strconv.Itoa and strconv.FormatInt will do the job. But Sprintf will use the package reflect, and it will allocate one more object, so it's not an efficient choice.

enter image description here

Michael M
  • 8,185
  • 2
  • 35
  • 51
Bryce
  • 3,046
  • 2
  • 19
  • 25
77

It is interesting to note that strconv.Itoa is shorthand for

func FormatInt(i int64, base int) string

with base 10

For Example:

strconv.Itoa(123)

is equivalent to

strconv.FormatInt(int64(123), 10)
unclemeat
  • 5,029
  • 5
  • 28
  • 52
kgthegreat
  • 1,172
  • 9
  • 10
  • 11
    Interesting to note that calling FormatInt() directly instead of Itoa() saves 0.1 nanosecond according to the benchmark at https://stackoverflow.com/a/38077508/968244 – isapir Nov 17 '18 at 23:37
46

You can use fmt.Sprintf or strconv.FormatFloat

For example

package main

import (
    "fmt"
)

func main() {
    val := 14.7
    s := fmt.Sprintf("%f", val)
    fmt.Println(s)
}
Miki Tebeka
  • 13,428
  • 4
  • 37
  • 49
34

In this case both strconv and fmt.Sprintf do the same job but using the strconv package's Itoa function is the best choice, because fmt.Sprintf allocate one more object during conversion.

check the nenchmark result of both check the benchmark here: https://gist.github.com/evalphobia/caee1602969a640a4530

see https://play.golang.org/p/hlaz_rMa0D for example.

manigandand
  • 2,094
  • 2
  • 15
  • 21
  • 1
    @Boon In visible impact to your app? As always - it depends. Another object means one more object, beyond the obvious temporary small memory hit, needs to be garbage collected. If you are calling the function at high rates, for example as part of some serialization process used whenever a message is received from somewhere, it could have a significant impact. Since `fmt.Sprintf` and `strconv.iota` are similar in terms of ease of use and the above data shows iota to be faster with lower GC impact, it appears that `iota` should be used in general when a single integer needs converting. – Edward Nov 14 '18 at 10:38
  • 1
    Seems like premature optimization to me to be thinking at this level so soon. Best is to write readable code first. – Boon Nov 16 '18 at 17:44
  • @Boon They're equally readable. Might as well use the faster one. Also, what's to say a new Golang programmer isn't starting with something that does lots of these conversions? I'm an experienced programmer writing my first Golang code right now and am in that situation. – sudo Feb 20 '19 at 00:15
14

Converting int64:

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

fmt.Println(str)
// Prints "32"
Cae Vecchi
  • 868
  • 1
  • 10
  • 19
11

Another option:

package main
import "fmt"

func main() {
   n := 123
   s := fmt.Sprint(n)
   fmt.Println(s == "123")
}

https://golang.org/pkg/fmt#Sprint

Zombo
  • 1
  • 62
  • 391
  • 407
  • Thank you very much. This is the a convenient and easy to remember solution (my point of view). – guettli Jan 27 '23 at 09:55
8

ok,most of them have shown you something good. Let'me give you this:

// 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
  • 561
  • 4
  • 10
  • This is great! You may include uint+uint8-64 to have a complete list – evilReiko Jun 17 '21 at 07:25
  • Or you could just use `fmt.Sprint` that does the same (except for `time.Time` and `jsoncrack.Time` (a package that will add dependencies I have never heard of) values). – dolmen Jun 01 '22 at 17:21
4
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
  • 5,407
  • 2
  • 29
  • 44