add: strings and projects
This commit is contained in:
57
19-strings-runes-bytes/01-bytes-runes-strings-basics/main.go
Normal file
57
19-strings-runes-bytes/01-bytes-runes-strings-basics/main.go
Normal file
@ -0,0 +1,57 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
str := "hey"
|
||||
bytes := []byte{104, 101, 121}
|
||||
|
||||
// same as: []byte("hey")
|
||||
fmt.Printf(`"hey" as bytes : %d`+"\n", []byte(str))
|
||||
|
||||
// same as: string([]byte{104, 101, 121})
|
||||
fmt.Printf("bytes as string : %q\n", string(bytes))
|
||||
|
||||
// runes are unicode codepoints (numbers)
|
||||
fmt.Println()
|
||||
fmt.Printf("%c : %[1]d\n", 'h')
|
||||
fmt.Printf("%c : %[1]d\n", 'e')
|
||||
fmt.Printf("%c : %[1]d\n", 'y')
|
||||
|
||||
// a rune literal is typeless
|
||||
// you can put it in any numeric type
|
||||
var (
|
||||
anInt int = 'h'
|
||||
anInt8 int8 = 'h'
|
||||
anInt16 int16 = 'h'
|
||||
anInt32 int32 = 'h'
|
||||
|
||||
// rune literal's default type is: rune
|
||||
// so, you don't need to specify it.
|
||||
// aRune rune = 'h'
|
||||
aRune = 'h'
|
||||
|
||||
// and so on...
|
||||
)
|
||||
|
||||
fmt.Println()
|
||||
fmt.Printf("rune literals are typeless:\n\t%T %T %T %T %T\n",
|
||||
anInt, anInt8, anInt16, anInt32, aRune)
|
||||
|
||||
fmt.Println()
|
||||
|
||||
// all are the same rune
|
||||
|
||||
// beginning with go 1.13 you can type: 0b0110_1000 instead
|
||||
// fmt.Printf("%q as binary: %08[1]b\n", 0b0110_1000)
|
||||
fmt.Printf("%q in decimal: %[1]d\n", 104)
|
||||
fmt.Printf("%q in binary : %08[1]b\n", 'h')
|
||||
fmt.Printf("%q in hex : 0x%[1]x\n", 0x68)
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var start, stop int
|
||||
|
||||
if args := os.Args[1:]; len(args) == 2 {
|
||||
start, _ = strconv.Atoi(args[0])
|
||||
stop, _ = strconv.Atoi(args[1])
|
||||
}
|
||||
|
||||
if start == 0 || stop == 0 {
|
||||
start, stop = 'A', 'Z'
|
||||
}
|
||||
|
||||
fmt.Printf("%-10s %-10s %-10s %-12s\n%s\n",
|
||||
"literal", "dec", "hex", "encoded",
|
||||
strings.Repeat("-", 45))
|
||||
|
||||
for n := start; n <= stop; n++ {
|
||||
fmt.Printf("%-10c %-10[1]d %-10[1]x % -12x\n", n, string(n))
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
EXAMPLE UNICODE BLOCKS
|
||||
|
||||
1 byte
|
||||
------------------------------------------------------------
|
||||
asciiStart = '\u0001' -> 32
|
||||
asciiStop = '\u007f' -> 127
|
||||
|
||||
upperCaseStart = '\u0041' -> 65
|
||||
upperCaseStop = '\u005a' -> 90
|
||||
|
||||
lowerCaseStart = '\u0061' -> 97
|
||||
lowerCaseStop = '\u007a' -> 122
|
||||
|
||||
|
||||
2 bytes
|
||||
------------------------------------------------------------
|
||||
latin1Start = '\u0080' -> 161
|
||||
latin1Stop = '\u00ff' -> 255
|
||||
|
||||
|
||||
3 bytes
|
||||
------------------------------------------------------------
|
||||
dingbatStart = '\u2700' -> 9984
|
||||
dingbatStop = '\u27bf' -> 10175
|
||||
|
||||
|
||||
4 bytes
|
||||
------------------------------------------------------------
|
||||
emojiStart = '\U0001f600' -> 128512
|
||||
emojiStop = '\U0001f64f' -> 128591
|
||||
*/
|
@ -0,0 +1,72 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unicode/utf8"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func main() {
|
||||
str := "Yūgen ☯ 💀"
|
||||
|
||||
// can't change a string
|
||||
// a string is a read-only byte-slice
|
||||
// str[0] = 'N'
|
||||
// str[1] = 'o'
|
||||
|
||||
bytes := []byte(str)
|
||||
|
||||
// can change a byte slice
|
||||
// bytes[0] = 'N'
|
||||
// bytes[1] = 'o'
|
||||
|
||||
str = string(bytes)
|
||||
|
||||
fmt.Printf("%s\n", str)
|
||||
fmt.Printf("\t%d bytes\n", len(str))
|
||||
fmt.Printf("\t%d runes\n", utf8.RuneCountInString(str))
|
||||
fmt.Printf("% x\n", bytes)
|
||||
fmt.Printf("\t%d bytes\n", len(bytes))
|
||||
fmt.Printf("\t%d runes\n", utf8.RuneCount(bytes))
|
||||
|
||||
// fmt.Println()
|
||||
// for i, r := range str {
|
||||
// fmt.Printf("str[%2d] = % -12x = %q\n", i, string(r), r)
|
||||
// }
|
||||
|
||||
fmt.Println()
|
||||
fmt.Printf("1st byte : %c\n", str[0]) // ok
|
||||
fmt.Printf("2nd byte : %c\n", str[1]) // not ok
|
||||
fmt.Printf("2nd rune : %s\n", str[1:3]) // ok
|
||||
fmt.Printf("last rune : %s\n", str[len(str)-4:]) // ok
|
||||
|
||||
// disadvantage: each one is 4 bytes
|
||||
runes := []rune(str)
|
||||
|
||||
fmt.Println()
|
||||
fmt.Printf("%s\n", str)
|
||||
fmt.Printf("\t%d bytes\n", int(unsafe.Sizeof(runes[0]))*len(runes))
|
||||
fmt.Printf("\t%d runes\n", len(runes))
|
||||
|
||||
fmt.Printf("1st rune : %c\n", runes[0])
|
||||
fmt.Printf("2nd rune : %c\n", runes[1])
|
||||
fmt.Printf("first five : %c\n", runes[:5])
|
||||
|
||||
fmt.Println()
|
||||
|
||||
word := "öykü"
|
||||
fmt.Printf("%q in runes: %c\n", word, []rune(word))
|
||||
fmt.Printf("%q in bytes: % [1]x\n", word)
|
||||
|
||||
fmt.Printf("%s %s\n", word[:2], []byte{word[0], word[1]}) // ö
|
||||
fmt.Printf("%c\n", word[2]) // y
|
||||
fmt.Printf("%c\n", word[3]) // k
|
||||
fmt.Printf("%s %s\n", word[4:], []byte{word[4], word[5]}) // ü
|
||||
}
|
46
19-strings-runes-bytes/04-rune-decoding/01/main.go
Normal file
46
19-strings-runes-bytes/04-rune-decoding/01/main.go
Normal file
@ -0,0 +1,46 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
func main() {
|
||||
const text = `Galaksinin Batı Sarmal Kolu'nun bir ucunda, haritası bile çıkarılmamış ücra bir köşede, gözlerden uzak, küçük ve sarı bir güneş vardır.
|
||||
|
||||
Bu güneşin yörüngesinde, kabaca yüz kırksekiz milyon kilometre uzağında, tamamıyla önemsiz ve mavi-yeşil renkli, küçük bir gezegen döner.
|
||||
|
||||
Gezegenin maymun soyundan gelen canlıları öyle ilkeldir ki dijital kol saatinin hâlâ çok etkileyici bir buluş olduğunu düşünürler.`
|
||||
|
||||
r, size := utf8.DecodeRuneInString("öykü")
|
||||
fmt.Printf("rune: %c size: %d bytes.\n", r, size)
|
||||
|
||||
r, size = utf8.DecodeRuneInString("ykü")
|
||||
fmt.Printf("rune: %c size: %d bytes.\n", r, size)
|
||||
|
||||
r, size = utf8.DecodeRuneInString("kü")
|
||||
fmt.Printf("rune: %c size: %d bytes.\n", r, size)
|
||||
|
||||
r, size = utf8.DecodeRuneInString("ü")
|
||||
fmt.Printf("rune: %c size: %d bytes.\n", r, size)
|
||||
|
||||
// for range loop automatically decodes the runes
|
||||
// but it gives you the position of the current rune
|
||||
// instead of its size.
|
||||
|
||||
// for _, r := range text {}
|
||||
for i := 0; i < len(text); {
|
||||
r, size := utf8.DecodeRuneInString(text[i:])
|
||||
fmt.Printf("%c", r)
|
||||
|
||||
i += size
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"testing"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
/*
|
||||
Let's run this program to see the speed differences.
|
||||
|
||||
benchDecoder 30000000 46.2 ns/op --> BEST
|
||||
benchForRange 30000000 53.0 ns/op --> MEDIOCRE
|
||||
benchConcater 20000000 93.7 ns/op --> WORST
|
||||
*/
|
||||
|
||||
var word = []byte("öykü")
|
||||
|
||||
func decoder(w []byte) {
|
||||
_, size := utf8.DecodeRune(word)
|
||||
copy(w[:size], bytes.ToUpper(w[:size]))
|
||||
}
|
||||
|
||||
func forRange(w []byte) {
|
||||
var size int
|
||||
for i := range string(w) {
|
||||
if i > 0 {
|
||||
size = i
|
||||
break
|
||||
}
|
||||
}
|
||||
copy(w[:size], bytes.ToUpper(w[:size]))
|
||||
}
|
||||
|
||||
var globalString string
|
||||
|
||||
func concater(w []byte) {
|
||||
runes := []rune(string(w))
|
||||
runes[0] = unicode.ToUpper(runes[0])
|
||||
globalString = string(runes)
|
||||
}
|
||||
|
||||
func bench(technique func([]byte)) testing.BenchmarkResult {
|
||||
return testing.Benchmark(func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
technique(word)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("benchDecoder", bench(decoder))
|
||||
fmt.Println("benchForRange", bench(forRange))
|
||||
fmt.Println("benchConcater", bench(concater))
|
||||
}
|
43
19-strings-runes-bytes/04-rune-decoding/02/main.go
Normal file
43
19-strings-runes-bytes/04-rune-decoding/02/main.go
Normal file
@ -0,0 +1,43 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
func main() {
|
||||
word := []byte("öykü")
|
||||
fmt.Printf("%s = % [1]x\n", word)
|
||||
|
||||
// how to make the first rune uppercase?
|
||||
|
||||
// you need to find the starting and ending position of the first rune
|
||||
|
||||
// 1st way: `for range`
|
||||
// you can't get the runes by range overing a byte slice
|
||||
// first, you need to convert it to a string
|
||||
var size int
|
||||
for i := range string(word) {
|
||||
if i > 0 {
|
||||
size = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 2nd way: let's do it using the utf8 package's DecodeRune function
|
||||
_, size = utf8.DecodeRune(word)
|
||||
|
||||
// overwrite the current bytes with the new uppercased bytes
|
||||
copy(word[:size], bytes.ToUpper(word[:size]))
|
||||
|
||||
// to get printed bytes/runes need to be encoded in a string
|
||||
fmt.Printf("%s = % [1]x\n", word)
|
||||
}
|
45
19-strings-runes-bytes/05-internals/main.go
Normal file
45
19-strings-runes-bytes/05-internals/main.go
Normal file
@ -0,0 +1,45 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// empty := ""
|
||||
// dump(empty)
|
||||
|
||||
hello := "hello"
|
||||
dump(hello)
|
||||
dump("hello")
|
||||
dump("hello!")
|
||||
|
||||
for i := range hello {
|
||||
dump(hello[i : i+1])
|
||||
}
|
||||
|
||||
dump(string([]byte(hello)))
|
||||
dump(string([]byte(hello)))
|
||||
dump(string([]rune(hello)))
|
||||
}
|
||||
|
||||
// StringHeader is used by a string value
|
||||
// In practice, you should use: reflect.Header
|
||||
type StringHeader struct {
|
||||
// points to a backing array's item
|
||||
pointer uintptr // where it starts
|
||||
length int // where it ends
|
||||
}
|
||||
|
||||
// dump prints the string header of a string value
|
||||
func dump(s string) {
|
||||
ptr := *(*StringHeader)(unsafe.Pointer(&s))
|
||||
fmt.Printf("%q: %+v\n", s, ptr)
|
||||
}
|
Reference in New Issue
Block a user