Is it possible to convert a string to an io.Writer type in Golang?
I will be using this string in fmt.Fprintf() but I am unable to convert the type.
You can't write into a string, strings in Go are immutable.
The best alternatives are the bytes.Buffer and since Go 1.10 the faster strings.Builder types: they implement io.Writer so you can write into them, and you can obtain their content as a string with Buffer.String() and Builder.String(), or as a byte slice with Buffer.Bytes().
You can also have a string as the initial content of the buffer if you create the buffer with bytes.NewBufferString():
s := "Hello"
buf := bytes.NewBufferString(s)
fmt.Fprint(buf, ", World!")
fmt.Println(buf.String())
Output (try it on the Go Playground):
Hello, World!
If you want to append a variable of type string (or any value of string type), you can simply use Buffer.WriteString() (or Builder.WriteString()):
s2 := "to be appended"
buf.WriteString(s2)
Or:
fmt.Fprint(buf, s2)
Also note that if you just want to concatenate 2 strings, you don't need to create a buffer and use fmt.Fprintf(), you can simply use the + operator to concatenate them:
s := "Hello"
s2 := ", World!"
s3 := s + s2 // "Hello, World!"
Also see: Golang: format a string without printing?
It may also be of interest: What's the difference between ResponseWriter.Write and io.WriteString?
I saw the other answer mention strings.Builder, but I didn't see an example. So here you go:
package main
import (
"fmt"
"strings"
)
func main() {
b := new(strings.Builder)
fmt.Fprint(b, "south north")
println(b.String())
}
https://golang.org/pkg/strings#Builder
Use bytes.Buffer which implements the Write() method.
import "bytes"
writer := bytes.NewBufferString("your string")
Related
I have a string like this:
package main
import "fmt"
func main() {
some := "p1k4"
for i, j := range some {
fmt.Println()
}
}
I want take each two consecutive characters in the string and print them. the output should like p1, 1k, k4, 4p.
I have tried it and still having trouble finding the answer, how should I write the code in go and get the output I want?
Go stores strings in memory as their UTF-8 encoded byte sequence. This maps ASCII charactes one-to-one in bytes, but characters outside of that range map to multiple bytes.
So I would advise to use the for range loop over a string, which ranges over the runes (characters) of the string, properly decoding multi-byte runes. This has the advantage that it does not require allocation (unlike converting the string to []rune). You may also print the pairs using fmt.Printf("%c%c", char1, char2), which also will not require allocation (unlike converting runes back to string and concatenating them).
To learn more about strings, characters and runes in Go, read blog post: Strings, bytes, runes and characters in Go
Since the loop only returns the "current" rune in the iteration (but not the previous or the next rune), use another variable to store the previous (and first) runes so you have access to them when printing.
Let's write a function that prints the pairs as you want:
func printPairs(s string) {
var first, prev rune
for i, r := range s {
if i == 0 {
first, prev = r, r
continue
}
fmt.Printf("%c%c, ", prev, r)
prev = r
}
// Print last pair: prev is the last rune
fmt.Printf("%c%c\n", prev, first)
}
Testing it with your input and with another string that has multi-byte runes:
printPairs("p1k4")
printPairs("Go-世界")
Output will be (try it on the Go Playground):
p1, 1k, k4, 4p
Go, o-, -世, 世界, 界G
package main
import (
"fmt"
)
func main() {
str := "12345"
for i := 0; i < len(str); i++ {
fmt.Println(string(str[i]) + string(str[(i+1)%len(str)]))
}
}
This is a simple for loop over your string with the first character appended at the back:
package main
import "fmt"
func main() {
some := "p1k4"
ns := some + string(some[0])
for i := 0; i < len(ns)-1; i++ {
fmt.Println(ns[i:i+2])
}
}
I have this a problem with character conversion. It all starts with this string: U+1F618. According to fileformat.info, this string is now (almost) in the HTML Entity (hex) notation.
But I need this character to be converted into a C/C++/Java source code-notation. I really don't know if this is the official name for the notation, but I assume this site to be correct :).
So basically my question is, instead of outputting to the real emoji, how can I get the value \uD83D\uDE18?
package main
import (
"fmt"
"html"
"strconv"
"strings"
)
func main() {
original := "\\U0001f618"
// Hex String
h := strings.ReplaceAll(original, "\\U", "0x")
// Hex to Int
i, _ := strconv.ParseInt(h, 0, 64)
// Unescape the string (HTML Entity -> String).
str := html.UnescapeString(string(i))
// Display the emoji.
fmt.Println(str)
// but I want something like this: \uD83D\uDE18
}
If you have the input as a string, e.g.
s := "\\U0001f618"
You may use strconv.Unquote() to unquote it. Be sure the string you pass to it is quoted (it must be wrapped with backticks or double quotes):
s2, err := strconv.Unquote(`"` + s + `"`)
fmt.Println(s2, err)
This will give you an s2 string that contains your emoji:
😘 <nil>
Java's string model is a char[] which contains the UTF-16 code points. Go's memory model of string is the UTF-8 encoded byte sequence.
To convert a Go string to UTF-16, you may use the unicode/utf16 package of the standard lib. For example utf16.Encode() encodes a series of runes (unicode codepoints) to UTF-16. You get a series of runes from a Go string with a simple type conversion: []rune("some string").
u16 := utf16.Encode([]rune(s2))
fmt.Printf("%X\n", u16)
The above prints the UTF16 codepoints in hexadecimal format:
[D83D DE18]
To get the format you want, use this loop:
buf := &strings.Builder{}
for _, v := range u16 {
fmt.Fprintf(buf, "\\u%X", v)
}
fmt.Println(buf.String())
Which outputs:
\uD83D\uDE18
Try the examples on the Go Playground.
You can capture this series of conversions in a function:
func convert(s string) (string, error) {
s2, err := strconv.Unquote(`"` + s + `"`)
if err != nil {
return "", err
}
buf := &strings.Builder{}
for _, v := range utf16.Encode([]rune(s2)) {
fmt.Fprintf(buf, "\\u%X", v)
}
return buf.String(), nil
}
Using it:
fmt.Println(convert("\\U0001f618"))
Which outputs (try it on the Go Playground):
\uD83D\uDE18 <nil>
I am trying to concatenate an integer with an existing string by casting and the appending using +. But it doesn't work.
package main
import (
"fmt"
)
func main() {
a := 4
b := "The value of a is "
fmt.Println(b + string(a))
}
This prints a garbage character on go playground and nothing on the Unix terminal. What could be the reason for this? What is incorrect with this method?
From the Go language spec:
Converting a signed or unsigned integer value to a string type yields a string containing the UTF-8 representation of the integer.
In order to achieve the desired result, you need to convert your int to a string using a method like strconv.Itoa:
package main
import (
"fmt"
"strconv"
)
func main() {
a := 4
b := "The value of a is "
fmt.Println(b + strconv.Itoa(a))
}
Use fmt.Sprintf or Printf; no casting required:
fmt.Sprintf("%s%d",s,i)
How do I obtain the alphabet value from the hex value in Go?
package main
import (
"encoding/hex"
"fmt"
)
func main() {
a := []byte{0x61}
c := hex.Dump(a)
fmt.Println(c,a)
}
http://play.golang.org/p/7iAs2kKw5v
You could use a fmt.Printf() format (example):
func main() {
a := []byte{0x61}
c := hex.Dump(a)
fmt.Printf("'%+v' -- '%s'\n", c, a)
}
Output:
'00000000 61 |a|
' -- 'a'
The %s format is enough to convert the 0x61 in 'a'.
Your question is a little misleading.
Based on your question what you really want is convert a byte value or a []byte (byte slice) to a string or character (which is more or less a rune in Go).
Henceforth I will separate the single byte value from the []byte using these variables:
b := byte(0x61)
bs := []byte{b}
To convert it to a string, you can simply use a conversion which is the cleanest and most simple:
s := string(bs)
If you want it as a "character", you can convert it to a rune:
r := rune(b)
Another solution is using fmt.Printf() as mentioned in VonC's answer and using the %s verb which is:
%s the uninterpreted bytes of the string or slice
You might want to take a look at these alternatives:
%c the character represented by the corresponding Unicode code point
%q a single-quoted character literal safely escaped with Go syntax.
%q accepts both a byte, []byte and rune.
See this litte example to demonstrate these (try it on the Go Playground):
b := byte(0x61)
bs := []byte{b}
fmt.Printf("%s\n", bs)
fmt.Printf("%c\n", b)
fmt.Println(string(bs))
fmt.Printf("%q\n", bs)
fmt.Printf("%q\n", b)
fmt.Printf("%q\n", rune(b))
Output:
a
a
a
"a"
'a'
'a'
If you need the result as a string, you can use the fmt.Sprintf() variant mentioned in satran's answer like this:
s := fmt.Sprintf("%s", bs)
But it's easier to just use the string conversion (string(bs)).
If you just want the string you can you fmt.Sprintf.
package main
import (
"fmt"
)
func main() {
a := []byte{0x61}
c := fmt.Sprintf("%s", a)
fmt.Println(c)
}
I'm currently working with a bit of code at the moment, that involves a var with type []interface{}
It has values within it, that I could easily access like so:
//given that args is of type []interface{}
name := args[0]
age := args[1] //ect...
This is fine, but I'd like to be able to use the strings Join function, and it would typically error due to it requiring type []string and not type []interface{}.
What would be the most appropriate solution to be able to use the Join function, I'd guess maybe some sort on conversion?
You need to construct a new array of type []string in order to use strings.Join:
import "fmt"
import "strings"
func main() {
s1 := []interface{}{"a", "b", "c"}
s2 := make([]string, len(s1))
for i, s := range s1 {
s2[i] = s.(string)
}
fmt.Println(strings.Join(s2, ", "))
}
See the related Golang FAQ entry: can I convert a []T to an []interface{}?