Add lecture 01
This commit is contained in:
parent
6ff6eaa3fa
commit
34877ef4e3
12 changed files with 874 additions and 0 deletions
3
lectures/01-basics/append/append.go
Normal file
3
lectures/01-basics/append/append.go
Normal file
|
@ -0,0 +1,3 @@
|
|||
package main
|
||||
|
||||
func append(s []int, elem ...int) []int
|
27
lectures/01-basics/countwords/main.go
Normal file
27
lectures/01-basics/countwords/main.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"golang.org/x/net/html"
|
||||
)
|
||||
|
||||
func CountWordsAndImages(url string) (words, images int, err error) {
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
doc, err := html.Parse(resp.Body)
|
||||
resp.Body.Close()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("parsing HTML: %s", err)
|
||||
return
|
||||
}
|
||||
words, images = countWordsAndImages(doc)
|
||||
return
|
||||
}
|
||||
|
||||
func countWordsAndImages(n *html.Node) (words, images int) {
|
||||
return
|
||||
}
|
13
lectures/01-basics/exported/example.go
Normal file
13
lectures/01-basics/exported/example.go
Normal file
|
@ -0,0 +1,13 @@
|
|||
package example
|
||||
|
||||
const C0 = 9.8
|
||||
const c1 = 15
|
||||
|
||||
var V0 string
|
||||
var v1 string
|
||||
|
||||
func F0() {}
|
||||
func f1() {}
|
||||
|
||||
type T0 int
|
||||
type t1 string
|
20
lectures/01-basics/flag/main.go
Normal file
20
lectures/01-basics/flag/main.go
Normal file
|
@ -0,0 +1,20 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
n = flag.Bool("n", false, "omit trailing newline")
|
||||
sep = flag.String("s", " ", "separator")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
fmt.Print(strings.Join(flag.Args(), *sep))
|
||||
if !*n {
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
32
lectures/01-basics/github/github.go
Normal file
32
lectures/01-basics/github/github.go
Normal file
|
@ -0,0 +1,32 @@
|
|||
package github
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type IssuesSearchResult struct{}
|
||||
|
||||
// SearchIssues queries the GitHub issue tracker.
|
||||
func SearchIssues(terms []string) (*IssuesSearchResult, error) {
|
||||
q := url.QueryEscape(strings.Join(terms, " "))
|
||||
resp, err := http.Get(IssuesURL + "?q=" + q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("search query failed: %s", resp.Status)
|
||||
}
|
||||
|
||||
var result IssuesSearchResult
|
||||
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &result, nil
|
||||
}
|
700
lectures/01-basics/lecture.slide
Normal file
700
lectures/01-basics/lecture.slide
Normal file
|
@ -0,0 +1,700 @@
|
|||
Базовые конструкции языка
|
||||
Лекция 2
|
||||
|
||||
Фёдор Короткий
|
||||
|
||||
* Имена
|
||||
|
||||
25 ключевых слов.
|
||||
|
||||
break default func interface select
|
||||
case defer go map struct
|
||||
chan else goto package switch
|
||||
const fallthrough if range type
|
||||
continue for import return var
|
||||
|
||||
* Predeclated identifiers
|
||||
|
||||
Константы
|
||||
|
||||
true false iota nil
|
||||
|
||||
Типы
|
||||
|
||||
int int8 int16 int32 int64
|
||||
uint uint8 uint16 uint32 uint64 uintptr
|
||||
float32 float64 complex128 complex64
|
||||
bool byte rune string error
|
||||
|
||||
Функции
|
||||
|
||||
make len cap new append copy close delete
|
||||
complex real imag
|
||||
panic recover
|
||||
|
||||
Идентификаторы можно переопределять по обычным правилам
|
||||
|
||||
// just example, don't do this
|
||||
var true = false
|
||||
|
||||
* Exported identifiers
|
||||
|
||||
Регистр первой буквы определяет видимость имени за пределами пакета
|
||||
|
||||
.play exported/example.go
|
||||
|
||||
Пакеты всегда называют в нижнем регистре и без подчеркиваний
|
||||
|
||||
fmt
|
||||
grpcmiddleware
|
||||
|
||||
* Declaration
|
||||
|
||||
- 4 типы объявлений `var`, `const`, `type`, `func`
|
||||
- Пакет состоит из множества `.go` файлов
|
||||
- Порядок объявлений в коде не важен
|
||||
|
||||
* var
|
||||
|
||||
Общая форма
|
||||
|
||||
var name type = expression
|
||||
|
||||
Примеры
|
||||
|
||||
var i, j, k int // int, int, int
|
||||
var b, f, s = true, 2.3, "four" // bool, float64, string
|
||||
var f, err = os.Open(name) // os.Open returns a file and an error
|
||||
|
||||
* short variable declaration
|
||||
|
||||
i, j := 0, 1
|
||||
|
||||
Существующим переменным присваиваются новые значения
|
||||
|
||||
in, err := os.Open(infile)
|
||||
// ...
|
||||
out, err := os.Create(outfile)
|
||||
|
||||
Но должна объявляться хотябы одна новая переменная
|
||||
|
||||
f, err := os.Open(infile)
|
||||
// ...
|
||||
f, err := os.Create(outfile) // compile error: no new variables
|
||||
|
||||
* pointers
|
||||
|
||||
x := 1
|
||||
p := &x // p, of type *int, points to x
|
||||
fmt.Println(*p) // "1"
|
||||
*p = 2
|
||||
fmt.Println(x)
|
||||
|
||||
* escape analysis
|
||||
|
||||
var p = f()
|
||||
|
||||
func f() *int {
|
||||
v := 1
|
||||
return &v
|
||||
}
|
||||
|
||||
* flag
|
||||
|
||||
.play flag/main.go
|
||||
|
||||
* new
|
||||
|
||||
`new(T)` создаёт новую переменную с типом `T`.
|
||||
|
||||
func newInt() *int {
|
||||
return new(int)
|
||||
}
|
||||
|
||||
func newInt() *int {
|
||||
var dummy int
|
||||
return &dummy
|
||||
}
|
||||
|
||||
* zero size type
|
||||
|
||||
p := new(int)
|
||||
q := new(int)
|
||||
fmt.Println(p == q) // "false"
|
||||
|
||||
p := new(struct{})
|
||||
q := new(struct{})
|
||||
fmt.Println(p == q) // "true" or "false", depending on implementation
|
||||
|
||||
* variable lifetime
|
||||
|
||||
Память освобождается, после того как переменая становится недостижимой.
|
||||
|
||||
Компилятор может переместить переменную со стека на кучу.
|
||||
|
||||
var global *int
|
||||
func f() {
|
||||
var x int
|
||||
x = 1
|
||||
global = &x
|
||||
}
|
||||
|
||||
И с кучи на стек.
|
||||
|
||||
func g() {
|
||||
y := new(int)
|
||||
*y = 1
|
||||
}
|
||||
|
||||
* type declaration
|
||||
|
||||
type name underlying-type
|
||||
|
||||
.play tempconv0/conv.go
|
||||
|
||||
* packages
|
||||
|
||||
- Файл `tempconv/types.go`
|
||||
|
||||
.play tempconv/tempconv.go
|
||||
|
||||
- Файл `tempconv/conv.go`
|
||||
|
||||
.play tempconv/conv.go
|
||||
|
||||
* packages
|
||||
|
||||
fmt.Printf("Brrrr! %v\n", tempconv.AbsoluteZeroC)
|
||||
|
||||
fmt.Println(tempconv.CToF(tempconv.BoilingC))
|
||||
|
||||
* package initialization
|
||||
|
||||
var a = b + c // a initialized third, to 3
|
||||
var b = f() // b initialized second, to 2, by calling f
|
||||
var c = 1 // c initialized first, to 1
|
||||
|
||||
func f() int { return c + 1 }
|
||||
|
||||
* package initialization
|
||||
|
||||
.play popcount/popcount.go
|
||||
|
||||
* scope
|
||||
|
||||
.play scope/scope.go
|
||||
|
||||
* scope
|
||||
|
||||
.play scope/if.go
|
||||
|
||||
* scope if
|
||||
|
||||
- Неправильно
|
||||
|
||||
if f, err := os.Open(fname); err != nil { // compile error: unused: f
|
||||
return err
|
||||
}
|
||||
f.ReadByte() // compile error: undefined f
|
||||
f.Close() // compile error: undefined f
|
||||
|
||||
- Правильно
|
||||
|
||||
f, err := os.Open(fname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.ReadByte()
|
||||
f.Close()
|
||||
|
||||
* scope
|
||||
|
||||
var cwd string
|
||||
|
||||
func init() {
|
||||
cwd, err := os.Getwd() // NOTE: wrong!
|
||||
if err != nil {
|
||||
log.Fatalf("os.Getwd failed: %v", err)
|
||||
}
|
||||
log.Printf("Working directory = %s", cwd)
|
||||
}
|
||||
|
||||
* strings
|
||||
|
||||
`string` - неизменяемая последовательность байт.
|
||||
|
||||
`s[i]` - обращается к i-тому байту (не символу).
|
||||
|
||||
var s = "hello"
|
||||
|
||||
var doc = `Go is a tool for managing Go source code.
|
||||
|
||||
Usage:
|
||||
go command [arguments]
|
||||
...
|
||||
`
|
||||
|
||||
* unicode
|
||||
|
||||
Символы кодируются числами.
|
||||
|
||||
type rune int32
|
||||
|
||||
Кодировка utf8
|
||||
|
||||
0xxxxxx runes 0−127
|
||||
11xxxxx 10xxxxxx 128−2047
|
||||
110xxxx 10xxxxxx 10xxxxxx 2048−65535
|
||||
1110xxx 10xxxxxx 10xxxxxx 10xxxxxx 65536−0x10ffff
|
||||
|
||||
Разница между рунами и байтами
|
||||
|
||||
import "unicode/utf8"
|
||||
|
||||
func countRunes() {
|
||||
s := "Hello, 世界"
|
||||
fmt.Println(len(s)) // "13"
|
||||
fmt.Println(utf8.RuneCountInString(s)) // "9"
|
||||
}
|
||||
|
||||
* utf8
|
||||
|
||||
for i := 0; i < len(s); {
|
||||
r, size := utf8.DecodeRuneInString(s[i:])
|
||||
fmt.Printf("%d\t%c\n", i, r)
|
||||
i += size
|
||||
}
|
||||
|
||||
Декодирование utf8 встроено в язык
|
||||
|
||||
for i, r := range "Hello, 世界" {
|
||||
fmt.Printf("%d\t%q\t%d\n", i, r, r)
|
||||
}
|
||||
|
||||
runes := []rune("Hello, 世界")
|
||||
s := string(runes)
|
||||
|
||||
Некорректный байт превращается _unicode_replacement_character_ `'\uFFFD'`.
|
||||
|
||||
- Может ли строка `string([]rune(s))` быть больше `s`?
|
||||
|
||||
* stdlib
|
||||
|
||||
- `strings` - HasSuffix, Split, Join, etc.
|
||||
- `bytes` - аналог `strings` для `[]byte`.
|
||||
- `unicode` - IsDigit, IsLetter.
|
||||
- `strconv` - конвертация между строкой и `int`, `float`.
|
||||
- `path` - работа с unix путями
|
||||
- `filepath` - работа с путями текущей платформы
|
||||
|
||||
* []byte
|
||||
|
||||
s := "abc"
|
||||
b := []byte(s)
|
||||
s2 := string(b)
|
||||
|
||||
* bytes.Buffer
|
||||
|
||||
func intsToString(values []int) string {
|
||||
var buf bytes.Buffer
|
||||
buf.WriteByte('[')
|
||||
for i, v := range values {
|
||||
if i > 0 {
|
||||
buf.WriteString(", ")
|
||||
}
|
||||
fmt.Fprintf(&buf, "%d", v)
|
||||
}
|
||||
buf.WriteByte(']')
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
* constants
|
||||
|
||||
const (
|
||||
a = 1
|
||||
b
|
||||
c = 2
|
||||
d
|
||||
)
|
||||
|
||||
fmt.Println(a, b, c, d) // "1 1 2 2"
|
||||
|
||||
type Weekday int
|
||||
const (
|
||||
Sunday Weekday = iota
|
||||
Monday
|
||||
Tuesday
|
||||
)
|
||||
|
||||
type Flags uint
|
||||
const (
|
||||
FlagUp Flags = 1 << iota // is up
|
||||
FlagBroadcast // supports broadcast access capability
|
||||
FlagLoopback // is a loopback interface
|
||||
FlagPointToPoint // belongs to a point-to-point link
|
||||
FlagMulticast // supports multicast access capability
|
||||
)
|
||||
|
||||
* untyped constants
|
||||
|
||||
const (
|
||||
_ = 1 << (10 * iota)
|
||||
KiB
|
||||
MiB
|
||||
GiB
|
||||
TiB // (exceeds 1 << 32)
|
||||
PiB
|
||||
EiB
|
||||
ZiB // (exceeds 1 << 64)
|
||||
YiB
|
||||
)
|
||||
|
||||
- Компилятор гарантирует как минимум 256 бит точности
|
||||
|
||||
fmt.Println(YiB/ZiB) // "1024"
|
||||
|
||||
* arrays
|
||||
|
||||
var a [3]int
|
||||
var q [3]int = [3]int{1, 2, 3}
|
||||
var r [3]int = [3]int{1, 2}
|
||||
|
||||
d := [...]int{1, 2, 3}
|
||||
h := [...]int{99: -1}
|
||||
|
||||
- arrays are values
|
||||
|
||||
func zero(ptr *[32]byte) {
|
||||
*ptr = [32]byte{}
|
||||
}
|
||||
|
||||
* slices
|
||||
|
||||
- slice это тройка `data`, `len`, `cap`.
|
||||
|
||||
s := make([]int, 10)
|
||||
s = s[:0]
|
||||
s = s[:10]
|
||||
|
||||
* slices
|
||||
|
||||
// reverse reverses a slice of ints in place.
|
||||
func reverse(s []int) {
|
||||
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
}
|
||||
|
||||
* slices
|
||||
|
||||
var a, b []string
|
||||
fmt.Println(a == b)
|
||||
|
||||
var c []int
|
||||
d := []int{}
|
||||
fmt.Println(c != d)
|
||||
|
||||
// c == nil && d != nil
|
||||
// len(c) == 0 && len(d) == 0
|
||||
|
||||
* slices
|
||||
|
||||
make([]T, len) // len == cap
|
||||
make([]T, len, cap)
|
||||
|
||||
func append(s []T, elem ...T) []T
|
||||
|
||||
var s []int
|
||||
s = append(s, 1)
|
||||
s = append(s, 2, 3)
|
||||
|
||||
var a, b []int
|
||||
a = append(a, b...)
|
||||
|
||||
* stack
|
||||
|
||||
stack = append(stack, v) // push v
|
||||
|
||||
top := stack[len(stack)-1] // top of stack
|
||||
|
||||
stack = stack[:len(stack)-1] // pop
|
||||
|
||||
* copy
|
||||
|
||||
func remove(slice []int, i int) []int {
|
||||
copy(slice[i:], slice[i+1:])
|
||||
return slice[:len(slice)-1]
|
||||
}
|
||||
|
||||
* maps
|
||||
|
||||
ages := make(map[string]int)
|
||||
|
||||
ages := map[string]int{
|
||||
"alice": 31,
|
||||
"charlie": 34,
|
||||
}
|
||||
|
||||
ages := make(map[string]int)
|
||||
ages["alice"] = 31
|
||||
ages["charlie"] = 34
|
||||
|
||||
* maps
|
||||
|
||||
ages["alice"] = 32
|
||||
fmt.Println(ages["alice"]) // "32"
|
||||
fmt.Println(ages["bob"]) // "0"
|
||||
|
||||
delete(ages, "alice")
|
||||
|
||||
ages["bob"] += 1
|
||||
ages["bob"]++
|
||||
_ = &ages["bob"] // compile error: cannot take address of map element
|
||||
|
||||
* maps
|
||||
|
||||
for name, age := range ages {
|
||||
fmt.Printf("%s\t%d\n", name, age)
|
||||
}
|
||||
|
||||
var ages map[string]int
|
||||
fmt.Println(ages == nil) // "true"
|
||||
fmt.Println(len(ages) == 0) // "true"
|
||||
fmt.Println(ages["alice"]) // "0"
|
||||
ages["alice"] = 21 // panic
|
||||
|
||||
* maps
|
||||
|
||||
age, ok := ages["bob"]
|
||||
if !ok { /* "bob" is not a key in this map; age == 0. */ }
|
||||
|
||||
if age, ok := ages["bob"]; !ok { /* ... */ }
|
||||
|
||||
* set
|
||||
|
||||
var s0 map[string]bool
|
||||
var s1 map[string]struct{}
|
||||
|
||||
* struct
|
||||
|
||||
type Employee struct {
|
||||
ID int
|
||||
Name string
|
||||
Address string
|
||||
}
|
||||
|
||||
var dilbert Employee
|
||||
|
||||
dilbert.Salary -= 5000 // demoted, for writing too few lines of code
|
||||
|
||||
* struct
|
||||
|
||||
type tree struct {
|
||||
value int
|
||||
left, right *tree
|
||||
}
|
||||
|
||||
* struct
|
||||
|
||||
type Point struct{ X, Y int }
|
||||
p := Point{1, 2}
|
||||
p := Point{X: 1, Y: 2}
|
||||
|
||||
* comparing structs
|
||||
|
||||
type Point struct{ X, Y int }
|
||||
p := Point{1, 2}
|
||||
q := Point{2, 1}
|
||||
fmt.Println(p.X == q.X && p.Y == q.Y) // "false"
|
||||
fmt.Println(p == q) // "false"
|
||||
|
||||
Можно использовать структуры как ключи
|
||||
|
||||
type address struct {
|
||||
hostname string
|
||||
port int
|
||||
}
|
||||
|
||||
hits := make(map[address]int)
|
||||
hits[address{"golang.org", 443}]++
|
||||
|
||||
* struct embedding
|
||||
|
||||
type Point struct {
|
||||
X, Y int
|
||||
}
|
||||
|
||||
type Circle struct {
|
||||
Point
|
||||
Radius int
|
||||
}
|
||||
|
||||
c := Circle{
|
||||
Point: Point{X: 10, Y: 10},
|
||||
Radius: 1,
|
||||
}
|
||||
|
||||
c.X = 0
|
||||
|
||||
* json
|
||||
|
||||
type Movie struct {
|
||||
Title string
|
||||
Year int `json:"year"`
|
||||
Color bool `json:"color,omitempty"`
|
||||
Actors []string
|
||||
}
|
||||
|
||||
- marshal
|
||||
|
||||
data, err := json.Marshal(movies)
|
||||
if err != nil {
|
||||
log.Fatalf("JSON marshaling failed: %s", err)
|
||||
}
|
||||
fmt.Printf("%s\n", data)
|
||||
|
||||
data, err := json.MarshalIndent(movies, "", " ")
|
||||
if err != nil {
|
||||
log.Fatalf("JSON marshaling failed: %s", err)
|
||||
}
|
||||
fmt.Printf("%s\n", data)
|
||||
|
||||
* unmarshal
|
||||
|
||||
var movie Movie
|
||||
if err := json.Unmarshal(data, &movie); err != nil {
|
||||
log.Fatalf("JSON unmarshaling failed: %s", err)
|
||||
}
|
||||
fmt.Println(movie)
|
||||
|
||||
* github
|
||||
|
||||
.play github/github.go /func Search/,/^}/
|
||||
|
||||
* functions
|
||||
|
||||
func name(parameter-list) (result-list) {
|
||||
body
|
||||
}
|
||||
|
||||
Примеры
|
||||
|
||||
func hypot(x, y float64) float64 {
|
||||
return math.Sqrt(x*x + y*y)
|
||||
}
|
||||
fmt.Println(hypot(3, 4)) // "5"
|
||||
|
||||
func f(i, j, k int, s, t string) { /* ... */ }
|
||||
func f(i int, j int, k int, s string, t string) { /* ... */ }
|
||||
|
||||
* multiple return values
|
||||
|
||||
func Get(url string) (*http.Responce, error) {
|
||||
// ...
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// ...
|
||||
}
|
||||
|
||||
func logAndGet(url string) (*http.Responce, error) {
|
||||
log.Printf("logAndGet %s", url)
|
||||
return Get(url)
|
||||
}
|
||||
|
||||
* named return values
|
||||
|
||||
.play countwords/main.go /func Count/,/^}/
|
||||
|
||||
* errors
|
||||
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Дополнительный контекст
|
||||
|
||||
doc, err := html.Parse(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing %s as HTML: %w", url, err)
|
||||
}
|
||||
|
||||
Текст ошибки должен быть в lowercase.
|
||||
|
||||
genesis: crashed: no parachute: G-switch failed: bad relay orientation
|
||||
|
||||
* EOF
|
||||
|
||||
package io
|
||||
|
||||
import "errors"
|
||||
|
||||
// EOF is the error returned by Read when no more input is available.
|
||||
var EOF = errors.New("EOF")
|
||||
|
||||
in := bufio.NewReader(os.Stdin)
|
||||
for {
|
||||
r, _, err := in.ReadRune()
|
||||
if err == io.EOF {
|
||||
break // finished reading
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("read failed: %v", err)
|
||||
}
|
||||
// ...use r...
|
||||
}
|
||||
|
||||
* variadic functions
|
||||
|
||||
func sum(vals ...int) int {
|
||||
total := 0
|
||||
for _, val := range vals {
|
||||
total += val
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
fmt.Println(sum()) // "0"
|
||||
fmt.Println(sum(3)) // "3"
|
||||
fmt.Println(sum(1, 2, 3, 4)) // "10"
|
||||
|
||||
values := []int{1, 2, 3, 4}
|
||||
fmt.Println(sum(values...))
|
||||
fmt.Println(sum(0, values...)) // compilation error
|
||||
|
||||
* function values
|
||||
|
||||
func Inc(i int) int { return i + 1 }
|
||||
|
||||
var f func(i int) int
|
||||
if f != nil {
|
||||
f = Inc
|
||||
}
|
||||
|
||||
f = func(i int) int {
|
||||
return i * 2
|
||||
}
|
||||
|
||||
* recursion
|
||||
|
||||
type Node struct {
|
||||
V int
|
||||
L, R *Node
|
||||
}
|
||||
|
||||
func PrintAll(w io.Writer, root *Node) {
|
||||
var visit func(n *Node)
|
||||
visit = func(n *Node) {
|
||||
fmt.Fprintln(w, n.V)
|
||||
if n.L != nil {
|
||||
visit(n.L)
|
||||
}
|
||||
if n.R != nil {
|
||||
visit(n.R)
|
||||
}
|
||||
}
|
||||
|
||||
visit(w, root)
|
||||
}
|
22
lectures/01-basics/popcount/popcount.go
Normal file
22
lectures/01-basics/popcount/popcount.go
Normal file
|
@ -0,0 +1,22 @@
|
|||
package popcount
|
||||
|
||||
// pc[i] is the population count of i.
|
||||
var pc [256]byte
|
||||
|
||||
func init() {
|
||||
for i := range pc {
|
||||
pc[i] = pc[i/2] + byte(i&1)
|
||||
}
|
||||
}
|
||||
|
||||
// PopCount returns the population count (number of set bits) of x.
|
||||
func PopCount(x uint64) int {
|
||||
return int(pc[byte(x>>(0*8))] +
|
||||
pc[byte(x>>(1*8))] +
|
||||
pc[byte(x>>(2*8))] +
|
||||
pc[byte(x>>(3*8))] +
|
||||
pc[byte(x>>(4*8))] +
|
||||
pc[byte(x>>(5*8))] +
|
||||
pc[byte(x>>(6*8))] +
|
||||
pc[byte(x>>(7*8))])
|
||||
}
|
16
lectures/01-basics/scope/if.go
Normal file
16
lectures/01-basics/scope/if.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func f() int { return 0 }
|
||||
func g(x int) int { return x }
|
||||
|
||||
func example() {
|
||||
if x := f(); x == 0 {
|
||||
fmt.Println(x)
|
||||
} else if y := g(x); x == y {
|
||||
fmt.Println(x, y)
|
||||
} else {
|
||||
fmt.Println(x, y)
|
||||
}
|
||||
}
|
11
lectures/01-basics/scope/scope.go
Normal file
11
lectures/01-basics/scope/scope.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
x := "hello"
|
||||
for _, x := range x {
|
||||
x := x + 'A' - 'a'
|
||||
fmt.Printf("%c", x) // "HELLO" (one letter per iteration)
|
||||
}
|
||||
}
|
4
lectures/01-basics/tempconv/conv.go
Normal file
4
lectures/01-basics/tempconv/conv.go
Normal file
|
@ -0,0 +1,4 @@
|
|||
package tempconv
|
||||
|
||||
func CToF(c Celsius) Fahrenheit { return Fahrenheit(c*9/5 + 32) }
|
||||
func FToC(f Fahrenheit) Celsius { return Celsius((f - 32) * 5 / 9) }
|
13
lectures/01-basics/tempconv/tempconv.go
Normal file
13
lectures/01-basics/tempconv/tempconv.go
Normal file
|
@ -0,0 +1,13 @@
|
|||
package tempconv
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Celsius float64
|
||||
type Fahrenheit float64
|
||||
|
||||
const (
|
||||
AbsoluteZeroC Celsius = -273.15
|
||||
)
|
||||
|
||||
func (c Celsius) String() string { return fmt.Sprintf("%g°C", c) }
|
||||
func (f Fahrenheit) String() string { return fmt.Sprintf("%g°F", f) }
|
13
lectures/01-basics/tempconv0/conv.go
Normal file
13
lectures/01-basics/tempconv0/conv.go
Normal file
|
@ -0,0 +1,13 @@
|
|||
package tempconv
|
||||
|
||||
type Celsius float64
|
||||
type Fahrenheit float64
|
||||
|
||||
const (
|
||||
AbsoluteZeroC Celsius = -273.15
|
||||
FreezingC Celsius = 0
|
||||
BoilingC Celsius = 100
|
||||
)
|
||||
|
||||
func CToF(c Celsius) Fahrenheit { return Fahrenheit(c*9/5 + 32) }
|
||||
func FToC(f Fahrenheit) Celsius { return Celsius((f - 32) * 5 / 9) }
|
Loading…
Reference in a new issue