add: strings and projects

This commit is contained in:
Inanc Gumus
2019-04-03 19:33:36 +03:00
parent 6e931e503b
commit 453774b601
17 changed files with 733 additions and 0 deletions

View 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)
}

View File

@ -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
*/

View File

@ -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]}) // ü
}

View 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()
}

View File

@ -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))
}

View 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)
}

View 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)
}