gofmt wat u know about it
This commit is contained in:
parent
f93bdba75c
commit
89f95f2ac5
@ -1,11 +1,11 @@
|
||||
// ## Hello World
|
||||
|
||||
// Here's an example Go program.
|
||||
package main
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
// It prints `Hello world`.
|
||||
func main() {
|
||||
fmt.Println("Hello world")
|
||||
fmt.Println("Hello world")
|
||||
}
|
||||
|
@ -2,22 +2,22 @@
|
||||
|
||||
// Go has various value types, including strings,
|
||||
// different types of numbers, booleans, etc.
|
||||
package main
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
|
||||
// Here are some strings, which can be added together.
|
||||
fmt.Println("Hello world")
|
||||
fmt.Println("Hello world")
|
||||
fmt.Println("Hello " + "other")
|
||||
|
||||
// Some examples of integers and floats.
|
||||
fmt.Println("1+1 =", 1+1)
|
||||
fmt.Println("1+1 =", 1+1)
|
||||
fmt.Println("7.0/3.0 =", 7.0/3.0)
|
||||
|
||||
// And booleans, which work as you'd expect.
|
||||
fmt.Println(true && false)
|
||||
fmt.Println(true && false)
|
||||
fmt.Println(true || false)
|
||||
fmt.Println(!true)
|
||||
}
|
||||
|
@ -7,10 +7,10 @@ import "fmt"
|
||||
func main() {
|
||||
// `var` declares 1 or more variables. The type comes
|
||||
// at the end.
|
||||
var x string = "Hello world"
|
||||
fmt.Println(x)
|
||||
var x string = "Hello world"
|
||||
fmt.Println(x)
|
||||
|
||||
// An example of declaring multiple `int` variables.
|
||||
var a, b int = 1, 2
|
||||
var a, b int = 1, 2
|
||||
fmt.Println(a, b)
|
||||
}
|
||||
|
@ -6,6 +6,6 @@ import "fmt"
|
||||
|
||||
func main() {
|
||||
// `x := val` is shorthand for `var x type = val`.
|
||||
x := "Hello assignment"
|
||||
fmt.Println(x)
|
||||
x := "Hello assignment"
|
||||
fmt.Println(x)
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ package main
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
var x [5]int
|
||||
x[4] = 100
|
||||
fmt.Println(x)
|
||||
fmt.Println(x[4])
|
||||
var x [5]int
|
||||
x[4] = 100
|
||||
fmt.Println(x)
|
||||
fmt.Println(x[4])
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ func main() {
|
||||
x[2] = 77
|
||||
x[3] = 82
|
||||
x[4] = 83
|
||||
|
||||
|
||||
var total float64 = 0
|
||||
for _, value := range x {
|
||||
total += value
|
||||
|
@ -5,12 +5,12 @@ package main
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
slice1 := []int{1,2,3}
|
||||
slice1 := []int{1, 2, 3}
|
||||
slice2 := append(slice1, 4, 5)
|
||||
fmt.Println(slice1)
|
||||
fmt.Println(slice2)
|
||||
slice3 := make([]int, 2)
|
||||
copy(slice3, slice1)
|
||||
fmt.Println(slice1)
|
||||
fmt.Println(slice3)
|
||||
fmt.Println(slice2)
|
||||
slice3 := make([]int, 2)
|
||||
copy(slice3, slice1)
|
||||
fmt.Println(slice1)
|
||||
fmt.Println(slice3)
|
||||
}
|
||||
|
@ -5,16 +5,16 @@ package main
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
x := make(map[string]int)
|
||||
x["this"] = 7
|
||||
x["that"] = 13
|
||||
fmt.Println(x)
|
||||
fmt.Println(x["this"])
|
||||
fmt.Println(x["missing"])
|
||||
fmt.Println(len(x))
|
||||
delete(x, "that")
|
||||
fmt.Println(x["that"])
|
||||
fmt.Println(len(x))
|
||||
_, present := x["that"]
|
||||
fmt.Println(present)
|
||||
x := make(map[string]int)
|
||||
x["this"] = 7
|
||||
x["that"] = 13
|
||||
fmt.Println(x)
|
||||
fmt.Println(x["this"])
|
||||
fmt.Println(x["missing"])
|
||||
fmt.Println(len(x))
|
||||
delete(x, "that")
|
||||
fmt.Println(x["that"])
|
||||
fmt.Println(len(x))
|
||||
_, present := x["that"]
|
||||
fmt.Println(present)
|
||||
}
|
||||
|
@ -5,16 +5,16 @@ package main
|
||||
import "fmt"
|
||||
|
||||
func avg(vals []float64) float64 {
|
||||
total := 0.0
|
||||
for _, val := range vals {
|
||||
total += val
|
||||
}
|
||||
return total / float64(len(vals))
|
||||
total := 0.0
|
||||
for _, val := range vals {
|
||||
total += val
|
||||
}
|
||||
return total / float64(len(vals))
|
||||
}
|
||||
|
||||
func main() {
|
||||
input := []float64{98,93,77,82,83}
|
||||
fmt.Println(input)
|
||||
output := avg(input)
|
||||
fmt.Println(output)
|
||||
input := []float64{98, 93, 77, 82, 83}
|
||||
fmt.Println(input)
|
||||
output := avg(input)
|
||||
fmt.Println(output)
|
||||
}
|
||||
|
@ -10,15 +10,15 @@ import "fmt"
|
||||
|
||||
// The `(int, int)` in this signature shows that the
|
||||
// function returns 2 ints.
|
||||
func vals() (int, int) {
|
||||
return 3, 7
|
||||
|
||||
func vals() (int, int) {
|
||||
return 3, 7
|
||||
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Use the 2 different return values from the call,
|
||||
// i.e. multiple assignement.
|
||||
x, y := vals()
|
||||
x, y := vals()
|
||||
fmt.Println(x)
|
||||
fmt.Println(y)
|
||||
}
|
||||
|
@ -5,29 +5,29 @@
|
||||
// number of arguments that will be needed for a function
|
||||
// ahead of time.
|
||||
|
||||
package main
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Varadic args are declared with `...type` and
|
||||
// passed in as a slice.
|
||||
func add(nums ...int) int {
|
||||
fmt.Print(nums, " ")
|
||||
func add(nums ...int) int {
|
||||
fmt.Print(nums, " ")
|
||||
total := 0
|
||||
for _, num := range nums {
|
||||
total += num
|
||||
for _, num := range nums {
|
||||
total += num
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
return total
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Varadic functions can be called in the usual way.
|
||||
fmt.Println(add(1, 2))
|
||||
fmt.Println(add(1, 2, 3))
|
||||
fmt.Println(add(1, 2))
|
||||
fmt.Println(add(1, 2, 3))
|
||||
|
||||
// If you already have multiple args in a slice,
|
||||
// apply them to a varadic function using `
|
||||
// func(slice...)`.
|
||||
nums := []int{1, 2, 3, 4}
|
||||
fmt.Println(add(nums...))
|
||||
}
|
||||
nums := []int{1, 2, 3, 4}
|
||||
fmt.Println(add(nums...))
|
||||
}
|
||||
|
@ -12,5 +12,5 @@ func factorial(x uint) uint {
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println(factorial(7))
|
||||
fmt.Println(factorial(7))
|
||||
}
|
||||
|
@ -9,5 +9,5 @@ func main() {
|
||||
// We'll use panic throught this book to check for
|
||||
// unexpected errors. This is the only program in the
|
||||
// book designed to panic.
|
||||
panic("O noes")
|
||||
}
|
||||
panic("O noes")
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ func one(xPtr *int) {
|
||||
}
|
||||
func main() {
|
||||
xPtr := new(int)
|
||||
fmt.Println(xPtr)
|
||||
fmt.Println(*xPtr)
|
||||
fmt.Println(xPtr)
|
||||
fmt.Println(*xPtr)
|
||||
one(xPtr)
|
||||
fmt.Println(xPtr)
|
||||
fmt.Println(*xPtr)
|
||||
|
@ -9,16 +9,16 @@ type Circle struct {
|
||||
}
|
||||
|
||||
func main() {
|
||||
cEmptyPtr := new(Circle)
|
||||
fmt.Println(cEmptyPtr)
|
||||
fmt.Println(*cEmptyPtr)
|
||||
|
||||
cValue := Circle{x: 1, y: 2, r: 5}
|
||||
fmt.Println(&cValue)
|
||||
fmt.Println(cValue)
|
||||
cEmptyPtr := new(Circle)
|
||||
fmt.Println(cEmptyPtr)
|
||||
fmt.Println(*cEmptyPtr)
|
||||
|
||||
cOrdered := Circle{1, 2, 5}
|
||||
fmt.Println(cOrdered)
|
||||
cValue := Circle{x: 1, y: 2, r: 5}
|
||||
fmt.Println(&cValue)
|
||||
fmt.Println(cValue)
|
||||
|
||||
cOrdered := Circle{1, 2, 5}
|
||||
fmt.Println(cOrdered)
|
||||
}
|
||||
|
||||
// todo: add field access
|
||||
|
@ -10,7 +10,7 @@ type Circle struct {
|
||||
}
|
||||
|
||||
func (c *Circle) area() float64 {
|
||||
return math.Pi * c.r*c.r
|
||||
return math.Pi * c.r * c.r
|
||||
}
|
||||
|
||||
type Rectangle struct {
|
||||
@ -30,10 +30,10 @@ func (r *Rectangle) area() float64 {
|
||||
}
|
||||
|
||||
func main() {
|
||||
circle := Circle{x: 0, y: 3, r: 5}
|
||||
fmt.Println(circle.area())
|
||||
rectangle := Rectangle {x1: 3, x2: 10, y1: 5, y2: 7}
|
||||
fmt.Println(rectangle.area())
|
||||
circle := Circle{x: 0, y: 3, r: 5}
|
||||
fmt.Println(circle.area())
|
||||
rectangle := Rectangle{x1: 3, x2: 10, y1: 5, y2: 7}
|
||||
fmt.Println(rectangle.area())
|
||||
}
|
||||
|
||||
// todo: pointer vs value receivers
|
||||
|
@ -14,7 +14,7 @@ type Circle struct {
|
||||
}
|
||||
|
||||
func (c *Circle) area() float64 {
|
||||
return math.Pi * c.r*c.r
|
||||
return math.Pi * c.r * c.r
|
||||
}
|
||||
|
||||
type Rectangle struct {
|
||||
@ -42,14 +42,14 @@ func totalArea(shapes ...Shape) float64 {
|
||||
}
|
||||
|
||||
func main() {
|
||||
circle := Circle{x: 0, y: 3, r: 5}
|
||||
rectangle := Rectangle {x1: 3, x2: 10, y1: 5, y2: 7}
|
||||
circle := Circle{x: 0, y: 3, r: 5}
|
||||
rectangle := Rectangle{x1: 3, x2: 10, y1: 5, y2: 7}
|
||||
|
||||
area := 0.0
|
||||
for _, s := range []Shape{&circle, &rectangle} {
|
||||
area += s.area()
|
||||
}
|
||||
fmt.Println(area)
|
||||
area := 0.0
|
||||
for _, s := range []Shape{&circle, &rectangle} {
|
||||
area += s.area()
|
||||
}
|
||||
fmt.Println(area)
|
||||
}
|
||||
|
||||
// todo: is this named wrong?
|
||||
|
@ -2,22 +2,25 @@
|
||||
|
||||
package main
|
||||
|
||||
import ("fmt"; "errors")
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func myFun(arg int) (int, error) {
|
||||
if arg == 42 {
|
||||
return -1, errors.New("Can't work with 42")
|
||||
|
||||
}
|
||||
return arg + 3, nil
|
||||
if arg == 42 {
|
||||
return -1, errors.New("Can't work with 42")
|
||||
|
||||
}
|
||||
return arg + 3, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
r, _ := myFun(7)
|
||||
fmt.Println(r)
|
||||
r, _ := myFun(7)
|
||||
fmt.Println(r)
|
||||
|
||||
_, e := myFun(42)
|
||||
fmt.Println(e)
|
||||
_, e := myFun(42)
|
||||
fmt.Println(e)
|
||||
}
|
||||
|
||||
// todo: custom errors
|
||||
|
@ -5,18 +5,18 @@ package main
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
x := make(map[string]string)
|
||||
x["here"] = "yes"
|
||||
x := make(map[string]string)
|
||||
x["here"] = "yes"
|
||||
|
||||
if name, ok := x["?"]; ok {
|
||||
fmt.Println(name)
|
||||
} else {
|
||||
fmt.Println("miss")
|
||||
}
|
||||
if name, ok := x["?"]; ok {
|
||||
fmt.Println(name)
|
||||
} else {
|
||||
fmt.Println("miss")
|
||||
}
|
||||
|
||||
if name, ok := x["here"]; ok {
|
||||
fmt.Println(name)
|
||||
}
|
||||
if name, ok := x["here"]; ok {
|
||||
fmt.Println(name)
|
||||
}
|
||||
}
|
||||
|
||||
// todo: note about use with errors
|
||||
|
@ -9,18 +9,18 @@ import "fmt"
|
||||
func f(n int) {
|
||||
for i := 0; i < 10; i++ {
|
||||
fmt.Println(n, ":", i)
|
||||
time.Sleep(time.Millisecond * time.Duration(rand.Intn(150)))
|
||||
time.Sleep(time.Millisecond * time.Duration(rand.Intn(150)))
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
for i := 0; i < 5; i++ {
|
||||
f(i)
|
||||
}
|
||||
fmt.Println()
|
||||
for i := 0; i < 5; i++ {
|
||||
go f(i)
|
||||
}
|
||||
f(i)
|
||||
}
|
||||
fmt.Println()
|
||||
for i := 0; i < 5; i++ {
|
||||
go f(i)
|
||||
}
|
||||
var input string
|
||||
fmt.Scanln(&input)
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import "fmt"
|
||||
|
||||
func main() {
|
||||
var messages chan string = make(chan string)
|
||||
go func() { messages <- "ping"}()
|
||||
msg := <- messages
|
||||
fmt.Println(msg)
|
||||
go func() { messages <- "ping" }()
|
||||
msg := <-messages
|
||||
fmt.Println(msg)
|
||||
}
|
||||
|
@ -7,6 +7,6 @@ import "fmt"
|
||||
func main() {
|
||||
var messages chan string = make(chan string, 1)
|
||||
messages <- "ping"
|
||||
msg := <- messages
|
||||
fmt.Println(msg)
|
||||
msg := <-messages
|
||||
fmt.Println(msg)
|
||||
}
|
||||
|
@ -12,14 +12,14 @@ func pinger(pings chan<- string) {
|
||||
|
||||
func ponger(pings <-chan string, pongs chan<- string) {
|
||||
for {
|
||||
<- pings
|
||||
pongs <- "pong"
|
||||
<-pings
|
||||
pongs <- "pong"
|
||||
}
|
||||
}
|
||||
|
||||
func printer(pongs <-chan string) {
|
||||
for {
|
||||
msg := <- pongs
|
||||
msg := <-pongs
|
||||
fmt.Println(msg)
|
||||
}
|
||||
}
|
||||
@ -32,6 +32,6 @@ func main() {
|
||||
go ponger(pings, pongs)
|
||||
go printer(pongs)
|
||||
|
||||
var input string
|
||||
var input string
|
||||
fmt.Scanln(&input)
|
||||
}
|
||||
|
@ -4,29 +4,29 @@
|
||||
// accross goroutines. Here's an example of waiting
|
||||
// for another goroutine to finish.
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
import "time"
|
||||
|
||||
// The `done` channel will be used for
|
||||
// synchronization.
|
||||
func worker(done chan<- bool) {
|
||||
fmt.Print("Working...")
|
||||
func worker(done chan<- bool) {
|
||||
fmt.Print("Working...")
|
||||
time.Sleep(time.Second)
|
||||
fmt.Println(" done")
|
||||
|
||||
// Send a value to notify that the work is done.
|
||||
done <- true
|
||||
done <- true
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Start a worker goroutine, give it the channel to
|
||||
// notify on.
|
||||
done := make(chan bool, 1)
|
||||
go worker(done)
|
||||
|
||||
done := make(chan bool, 1)
|
||||
go worker(done)
|
||||
|
||||
// Block until we can receive a value from the worker
|
||||
// over the channel.
|
||||
<- done
|
||||
}
|
||||
<-done
|
||||
}
|
||||
|
@ -8,27 +8,27 @@ import "fmt"
|
||||
func main() {
|
||||
c1 := make(chan string)
|
||||
c2 := make(chan string)
|
||||
d := make(chan bool, 1)
|
||||
d := make(chan bool, 1)
|
||||
|
||||
go func() {
|
||||
time.Sleep(time.Second * 1)
|
||||
c1 <- "from 1"
|
||||
c1 <- "from 1"
|
||||
}()
|
||||
go func() {
|
||||
time.Sleep(time.Second * 2)
|
||||
c2 <- "from 2"
|
||||
c2 <- "from 2"
|
||||
}()
|
||||
|
||||
go func() {
|
||||
for i :=0; i < 2; i ++ {
|
||||
for i := 0; i < 2; i++ {
|
||||
select {
|
||||
case msg1 := <- c1:
|
||||
case msg1 := <-c1:
|
||||
fmt.Println(msg1)
|
||||
case msg2 := <- c2:
|
||||
case msg2 := <-c2:
|
||||
fmt.Println(msg2)
|
||||
}
|
||||
}
|
||||
d <- true
|
||||
d <- true
|
||||
}()
|
||||
<- d
|
||||
<-d
|
||||
}
|
||||
|
@ -7,21 +7,21 @@ import "fmt"
|
||||
|
||||
func main() {
|
||||
c := make(chan string)
|
||||
d := make(chan bool, 1)
|
||||
d := make(chan bool, 1)
|
||||
|
||||
go func() {
|
||||
time.Sleep(time.Millisecond * 1500)
|
||||
c <- "ready"
|
||||
c <- "ready"
|
||||
}()
|
||||
|
||||
go func() {
|
||||
select {
|
||||
case msg := <- c:
|
||||
fmt.Println(msg)
|
||||
case <- time.After(time.Millisecond * 1000):
|
||||
fmt.Println("timeout")
|
||||
}
|
||||
d <- true
|
||||
}()
|
||||
<- d
|
||||
select {
|
||||
case msg := <-c:
|
||||
fmt.Println(msg)
|
||||
case <-time.After(time.Millisecond * 1000):
|
||||
fmt.Println("timeout")
|
||||
}
|
||||
d <- true
|
||||
}()
|
||||
<-d
|
||||
}
|
||||
|
@ -8,19 +8,19 @@ import "math/rand"
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
times := new([20]int)
|
||||
wait := new(sync.WaitGroup)
|
||||
for i := 0; i < 20; i++ {
|
||||
n := i
|
||||
wait.Add(1)
|
||||
go func() {
|
||||
opTime := rand.Intn(2000)
|
||||
time.Sleep(time.Duration(opTime) * time.Millisecond)
|
||||
fmt.Println(n)
|
||||
times[n] = opTime
|
||||
wait.Done()
|
||||
}()
|
||||
}
|
||||
wait.Wait()
|
||||
fmt.Println(*times)
|
||||
times := new([20]int)
|
||||
wait := new(sync.WaitGroup)
|
||||
for i := 0; i < 20; i++ {
|
||||
n := i
|
||||
wait.Add(1)
|
||||
go func() {
|
||||
opTime := rand.Intn(2000)
|
||||
time.Sleep(time.Duration(opTime) * time.Millisecond)
|
||||
fmt.Println(n)
|
||||
times[n] = opTime
|
||||
wait.Done()
|
||||
}()
|
||||
}
|
||||
wait.Wait()
|
||||
fmt.Println(*times)
|
||||
}
|
||||
|
@ -5,10 +5,10 @@ import "time"
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
throttle := time.Tick(time.Millisecond * 200)
|
||||
for {
|
||||
<- throttle
|
||||
go fmt.Println("rate-limited action")
|
||||
throttle := time.Tick(time.Millisecond * 200)
|
||||
for {
|
||||
<-throttle
|
||||
go fmt.Println("rate-limited action")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,17 +6,17 @@ import "time"
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
timer1 := time.NewTimer(time.Second)
|
||||
<- timer1.C
|
||||
fmt.Println("Timer 1 expired")
|
||||
stop1 := timer1.Stop()
|
||||
fmt.Println("Timer 2 stopped:", stop1)
|
||||
timer1 := time.NewTimer(time.Second)
|
||||
<-timer1.C
|
||||
fmt.Println("Timer 1 expired")
|
||||
stop1 := timer1.Stop()
|
||||
fmt.Println("Timer 2 stopped:", stop1)
|
||||
|
||||
timer2 := time.NewTimer(time.Second)
|
||||
go func() {
|
||||
<- timer2.C
|
||||
fmt.Println("Timer 2 expired")
|
||||
}()
|
||||
stop2 := timer2.Stop()
|
||||
fmt.Println("Timer 2 stopped:", stop2)
|
||||
timer2 := time.NewTimer(time.Second)
|
||||
go func() {
|
||||
<-timer2.C
|
||||
fmt.Println("Timer 2 expired")
|
||||
}()
|
||||
stop2 := timer2.Stop()
|
||||
fmt.Println("Timer 2 stopped:", stop2)
|
||||
}
|
||||
|
@ -3,25 +3,25 @@
|
||||
// The `sort` package implements sorting for builtins
|
||||
// and user-defined types. We'll look at some of the
|
||||
// sorts for builtins here.
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
import "sort"
|
||||
|
||||
func main() {
|
||||
// Sort methods are specific to the builtin type.
|
||||
// Sorting is in-place (doesn't return a new slice).
|
||||
strs := []string{"c", "a", "b"}
|
||||
sort.Strings(strs)
|
||||
fmt.Println(strs)
|
||||
strs := []string{"c", "a", "b"}
|
||||
sort.Strings(strs)
|
||||
fmt.Println(strs)
|
||||
|
||||
// Sorting methods are named after the type.
|
||||
ints := []int{7, 2, 4}
|
||||
sort.Ints(ints)
|
||||
sort.Ints(ints)
|
||||
fmt.Println(ints)
|
||||
|
||||
// Check if a slice is in sorted order.
|
||||
s := sort.IntsAreSorted(ints)
|
||||
s := sort.IntsAreSorted(ints)
|
||||
fmt.Println(s)
|
||||
}
|
||||
|
||||
|
@ -2,14 +2,18 @@
|
||||
|
||||
package main
|
||||
|
||||
import ("fmt" ; "sort")
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type Person struct {
|
||||
type Person struct {
|
||||
Name string
|
||||
Age int
|
||||
Age int
|
||||
}
|
||||
|
||||
type ByName []Person
|
||||
|
||||
func (this ByName) Len() int {
|
||||
return len(this)
|
||||
}
|
||||
@ -21,8 +25,9 @@ func (this ByName) Swap(i, j int) {
|
||||
}
|
||||
|
||||
type ByAge []Person
|
||||
|
||||
func (this ByAge) Len() int {
|
||||
return len(this)
|
||||
return len(this)
|
||||
}
|
||||
func (this ByAge) Less(i, j int) bool {
|
||||
return this[i].Age < this[j].Age
|
||||
@ -33,15 +38,15 @@ func (this ByAge) Swap(i, j int) {
|
||||
|
||||
func main() {
|
||||
kids := []Person{
|
||||
{"Jack", 10},
|
||||
{"Jack", 10},
|
||||
{"Jill", 9},
|
||||
{"Bob", 12},
|
||||
{"Bob", 12},
|
||||
}
|
||||
fmt.Println("Original:", kids)
|
||||
|
||||
sort.Sort(ByName(kids))
|
||||
fmt.Println("ByName: ", kids)
|
||||
|
||||
sort.Sort(ByAge(kids))
|
||||
fmt.Println("ByAge: ", kids)
|
||||
sort.Sort(ByName(kids))
|
||||
fmt.Println("ByName: ", kids)
|
||||
|
||||
sort.Sort(ByAge(kids))
|
||||
fmt.Println("ByAge: ", kids)
|
||||
}
|
||||
|
@ -1,95 +1,95 @@
|
||||
// ## Collection Functions
|
||||
|
||||
package main
|
||||
package main
|
||||
|
||||
import "strings"
|
||||
import "fmt"
|
||||
|
||||
func Index(elems []string, val string) int {
|
||||
for i, v := range elems {
|
||||
if v == val {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
for i, v := range elems {
|
||||
if v == val {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func Include(elems []string, val string) bool {
|
||||
return Index(elems, val) >= 0
|
||||
return Index(elems, val) >= 0
|
||||
}
|
||||
|
||||
func Any(elems []string, f func(string)bool) bool {
|
||||
for _, v := range elems {
|
||||
if f(v) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
func Any(elems []string, f func(string) bool) bool {
|
||||
for _, v := range elems {
|
||||
if f(v) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func All(elems []string, f func(string)bool) bool {
|
||||
for _, v := range elems {
|
||||
if !f(v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
func All(elems []string, f func(string) bool) bool {
|
||||
for _, v := range elems {
|
||||
if !f(v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func Filter(elems []string, f func(string)bool) []string {
|
||||
filtered := []string{}
|
||||
for _, v := range elems {
|
||||
if f(v) {
|
||||
filtered = append(filtered, v)
|
||||
}
|
||||
}
|
||||
return filtered
|
||||
func Filter(elems []string, f func(string) bool) []string {
|
||||
filtered := []string{}
|
||||
for _, v := range elems {
|
||||
if f(v) {
|
||||
filtered = append(filtered, v)
|
||||
}
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
func Map(elems []string, f func(string)string) []string {
|
||||
mapped := make([]string, len(elems))
|
||||
for i, v := range elems {
|
||||
mapped[i] = f(v)
|
||||
}
|
||||
return mapped
|
||||
func Map(elems []string, f func(string) string) []string {
|
||||
mapped := make([]string, len(elems))
|
||||
for i, v := range elems {
|
||||
mapped[i] = f(v)
|
||||
}
|
||||
return mapped
|
||||
}
|
||||
|
||||
func main() {
|
||||
var elems = []string{"peach", "apple", "pear", "banana"}
|
||||
var elems = []string{"peach", "apple", "pear", "banana"}
|
||||
|
||||
fmt.Println(Index(elems, "pear"))
|
||||
fmt.Println(Index(elems, "grape"))
|
||||
fmt.Println()
|
||||
fmt.Println(Index(elems, "pear"))
|
||||
fmt.Println(Index(elems, "grape"))
|
||||
fmt.Println()
|
||||
|
||||
fmt.Println(Include(elems, "pear"))
|
||||
fmt.Println(Include(elems, "grape"))
|
||||
fmt.Println()
|
||||
fmt.Println(Include(elems, "pear"))
|
||||
fmt.Println(Include(elems, "grape"))
|
||||
fmt.Println()
|
||||
|
||||
fmt.Println(Any(elems, func(v string) bool {
|
||||
return strings.HasPrefix(v, "p")
|
||||
}))
|
||||
fmt.Println(Any(elems, func(v string) bool {
|
||||
return strings.HasPrefix(v, "g")
|
||||
}))
|
||||
fmt.Println()
|
||||
fmt.Println(Any(elems, func(v string) bool {
|
||||
return strings.HasPrefix(v, "p")
|
||||
}))
|
||||
fmt.Println(Any(elems, func(v string) bool {
|
||||
return strings.HasPrefix(v, "g")
|
||||
}))
|
||||
fmt.Println()
|
||||
|
||||
fmt.Println(All(elems, func(v string) bool {
|
||||
return strings.Contains(v, "a")
|
||||
}))
|
||||
fmt.Println(All(elems, func(v string) bool {
|
||||
return strings.Contains(v, "p")
|
||||
}))
|
||||
fmt.Println()
|
||||
fmt.Println(All(elems, func(v string) bool {
|
||||
return strings.Contains(v, "a")
|
||||
}))
|
||||
fmt.Println(All(elems, func(v string) bool {
|
||||
return strings.Contains(v, "p")
|
||||
}))
|
||||
fmt.Println()
|
||||
|
||||
fmt.Println(Filter(elems, func(v string) bool {
|
||||
return strings.Contains(v, "p")
|
||||
}))
|
||||
fmt.Println()
|
||||
|
||||
fmt.Println(Map(elems, func(s string) string {
|
||||
return strings.ToUpper(s)
|
||||
}))
|
||||
fmt.Println()
|
||||
fmt.Println(Filter(elems, func(v string) bool {
|
||||
return strings.Contains(v, "p")
|
||||
}))
|
||||
fmt.Println()
|
||||
|
||||
fmt.Println(Map(elems, func(s string) string {
|
||||
return strings.ToUpper(s)
|
||||
}))
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
// todo: generics
|
||||
|
@ -6,7 +6,7 @@ import "strings"
|
||||
import "fm"
|
||||
|
||||
func p(o interface{}) {
|
||||
fmt.Println(o)
|
||||
fmt.Println(o)
|
||||
}
|
||||
|
||||
func main() {
|
||||
@ -15,8 +15,8 @@ func main() {
|
||||
p(strings.Count("test", "t"))
|
||||
p(strings.HasPrefix("test", "te"))
|
||||
p(strings.HasSuffix("test", "st"))
|
||||
p(strings.Index("test", "e"))
|
||||
p(strings.Join([]string{"a","b"}, "-"))
|
||||
p(strings.Index("test", "e"))
|
||||
p(strings.Join([]string{"a", "b"}, "-"))
|
||||
p(strings.Repeat("a", 5))
|
||||
p(strings.Replace("foo", "o", "0", -1))
|
||||
p(strings.Replace("foo", "o", "0", 1))
|
||||
|
@ -6,14 +6,14 @@ import "regexp"
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
m1, _ := regexp.MatchString("p[a-z]+ch", "apple")
|
||||
m2, _ := regexp.MatchString("p[a-z]+ch", "peach")
|
||||
fmt.Println(m1)
|
||||
fmt.Println(m2)
|
||||
m1, _ := regexp.MatchString("p[a-z]+ch", "apple")
|
||||
m2, _ := regexp.MatchString("p[a-z]+ch", "peach")
|
||||
fmt.Println(m1)
|
||||
fmt.Println(m2)
|
||||
|
||||
r1, _ := regexp.Compile("p[a-z]+ch")
|
||||
fmt.Println(r1.MatchString("apple"))
|
||||
fmt.Println(r1.MatchString("peach"))
|
||||
r1, _ := regexp.Compile("p[a-z]+ch")
|
||||
fmt.Println(r1.MatchString("apple"))
|
||||
fmt.Println(r1.MatchString("peach"))
|
||||
}
|
||||
|
||||
// todo: more
|
||||
|
@ -5,8 +5,8 @@ package main
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
arr := []byte("some bytes")
|
||||
str := string([]byte{'a', ' ', 's', 't', 'r', 'i', 'n', 'g'})
|
||||
fmt.Println(arr)
|
||||
fmt.Println(str)
|
||||
arr := []byte("some bytes")
|
||||
str := string([]byte{'a', ' ', 's', 't', 'r', 'i', 'n', 'g'})
|
||||
fmt.Println(arr)
|
||||
fmt.Println(str)
|
||||
}
|
||||
|
@ -6,32 +6,34 @@ import "encoding/json"
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
// data to bytes/string
|
||||
bol, _ := json.Marshal(true)
|
||||
fmt.Println(string(bol))
|
||||
// data to bytes/string
|
||||
bol, _ := json.Marshal(true)
|
||||
fmt.Println(string(bol))
|
||||
|
||||
num, _ := json.Marshal(1)
|
||||
fmt.Println(string(num))
|
||||
num, _ := json.Marshal(1)
|
||||
fmt.Println(string(num))
|
||||
|
||||
str, _ := json.Marshal("gopher")
|
||||
fmt.Println(string(str))
|
||||
|
||||
arr, _ := json.Marshal([]string{"apple", "peach", "pear"})
|
||||
fmt.Println(string(arr))
|
||||
str, _ := json.Marshal("gopher")
|
||||
fmt.Println(string(str))
|
||||
|
||||
hsh, _ := json.Marshal(map[string]int{"apple": 5, "lettuce": 7})
|
||||
fmt.Println(string(hsh))
|
||||
arr, _ := json.Marshal([]string{"apple", "peach", "pear"})
|
||||
fmt.Println(string(arr))
|
||||
|
||||
// string to data
|
||||
byt := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`)
|
||||
var dat map[string]interface{}
|
||||
err := json.Unmarshal(byt, &dat)
|
||||
if err != nil { panic(err) }
|
||||
fmt.Println(dat)
|
||||
hsh, _ := json.Marshal(map[string]int{"apple": 5, "lettuce": 7})
|
||||
fmt.Println(string(hsh))
|
||||
|
||||
name := dat["Name"].(string)
|
||||
fmt.Println(name)
|
||||
// string to data
|
||||
byt := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`)
|
||||
var dat map[string]interface{}
|
||||
err := json.Unmarshal(byt, &dat)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(dat)
|
||||
|
||||
parents := dat["Parents"].([]interface{})
|
||||
fmt.Println(parents)
|
||||
name := dat["Name"].(string)
|
||||
fmt.Println(name)
|
||||
|
||||
parents := dat["Parents"].([]interface{})
|
||||
fmt.Println(parents)
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
// ## Epochs
|
||||
|
||||
package main
|
||||
|
||||
package main
|
||||
|
||||
import "time"
|
||||
|
||||
func main() {
|
||||
// Use `time.Now` with `Unix` or `UnixNane` to get
|
||||
// elapsed time since the Unix epoch.
|
||||
now := time.Now()
|
||||
secs := now.Unix()
|
||||
nanos := now.UnixNano()
|
||||
now := time.Now()
|
||||
secs := now.Unix()
|
||||
nanos := now.UnixNano()
|
||||
|
||||
// There is no `UnixMillis`.
|
||||
millis := nanos / 1000000
|
||||
println("Secs: ", secs)
|
||||
println("Millis:", millis)
|
||||
println("Nanos: ", nanos)
|
||||
millis := nanos / 1000000
|
||||
println("Secs: ", secs)
|
||||
println("Millis:", millis)
|
||||
println("Nanos: ", nanos)
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import "time"
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
start := time.Now()
|
||||
time.Sleep(3 * time.Second)
|
||||
fmt.Println(time.Since(start))
|
||||
start := time.Now()
|
||||
time.Sleep(3 * time.Second)
|
||||
fmt.Println(time.Since(start))
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Random Numbers
|
||||
|
||||
package main
|
||||
|
||||
package main
|
||||
|
||||
// The `math/rand` package provides psuedo-random
|
||||
// numbers.
|
||||
import "math/rand"
|
||||
@ -10,30 +10,30 @@ import "fmt"
|
||||
func main() {
|
||||
// For example, `rand.Intn` returns a random `int` n,
|
||||
// `0 <= n < 100`.
|
||||
fmt.Print(rand.Intn(100), ",")
|
||||
fmt.Print(rand.Intn(100))
|
||||
fmt.Print(rand.Intn(100), ",")
|
||||
fmt.Print(rand.Intn(100))
|
||||
fmt.Println()
|
||||
|
||||
// `rand.Float64` returns a `float64` `f`,
|
||||
// `0.0 <= f < 1.0`.
|
||||
fmt.Println(rand.Float64())
|
||||
|
||||
fmt.Println(rand.Float64())
|
||||
|
||||
// To make the psuedo-random generator deterministic,
|
||||
// give it a well-known seed.
|
||||
s1 := rand.NewSource(42)
|
||||
r1 := rand.New(s1)
|
||||
|
||||
// Call the resulting `rand.Source` just like the
|
||||
// functions on the `rand` package.
|
||||
fmt.Print(r1.Intn(100), ",")
|
||||
fmt.Print(r1.Intn(100))
|
||||
s1 := rand.NewSource(42)
|
||||
r1 := rand.New(s1)
|
||||
|
||||
// Call the resulting `rand.Source` just like the
|
||||
// functions on the `rand` package.
|
||||
fmt.Print(r1.Intn(100), ",")
|
||||
fmt.Print(r1.Intn(100))
|
||||
fmt.Println()
|
||||
|
||||
// If you seed a source with the same number, it
|
||||
// produces the same sequence of random numbers.
|
||||
s2 := rand.NewSource(42)
|
||||
r2 := rand.New(s2)
|
||||
fmt.Print(r2.Intn(100), ",")
|
||||
fmt.Print(r2.Intn(100))
|
||||
fmt.Println()
|
||||
s2 := rand.NewSource(42)
|
||||
r2 := rand.New(s2)
|
||||
fmt.Print(r2.Intn(100), ",")
|
||||
fmt.Print(r2.Intn(100))
|
||||
fmt.Println()
|
||||
}
|
||||
|
@ -8,23 +8,23 @@ import "fmt"
|
||||
|
||||
func main() {
|
||||
// `64` tells how many bits of precision to parse.
|
||||
f, _ := strconv.ParseFloat("1.234", 64)
|
||||
f, _ := strconv.ParseFloat("1.234", 64)
|
||||
fmt.Println(f)
|
||||
|
||||
|
||||
// `0` means infer the base from the string.
|
||||
// `64` requires that the result fit in 64 bits.
|
||||
i, _ := strconv.ParseInt("123", 0, 64)
|
||||
println(i)
|
||||
i, _ := strconv.ParseInt("123", 0, 64)
|
||||
println(i)
|
||||
|
||||
// `ParseInt` will recognize hex-formatted numbers.
|
||||
d, _ := strconv.ParseInt("0x1b3e", 0, 64)
|
||||
d, _ := strconv.ParseInt("0x1b3e", 0, 64)
|
||||
println(d)
|
||||
|
||||
// `Atoi` is a convenienice function for `int` parsing.
|
||||
k, _ := strconv.Atoi("456")
|
||||
k, _ := strconv.Atoi("456")
|
||||
println(k)
|
||||
|
||||
// Parse functions return an error on bad input.
|
||||
_, e := strconv.Atoi("wat")
|
||||
_, e := strconv.Atoi("wat")
|
||||
fmt.Println(e)
|
||||
}
|
||||
|
@ -13,5 +13,4 @@ func main() {
|
||||
fmt.Print(string(contents))
|
||||
}
|
||||
|
||||
|
||||
// todo: streaming reads
|
||||
|
@ -5,7 +5,7 @@ package main
|
||||
import "os"
|
||||
|
||||
func main() {
|
||||
file, err := os.Create("xx-file-write.txt")
|
||||
file, err := os.Create("xx-file-write.txt")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -2,25 +2,24 @@
|
||||
|
||||
// Use `os.Args` to access command-line arguments and
|
||||
// the name of the program.
|
||||
package main
|
||||
|
||||
package main
|
||||
|
||||
import "os"
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
// `os.Args` includes the program name as the first
|
||||
// value.
|
||||
argsWithProg := os.Args
|
||||
argsWithoutProg := os.Args[1:]
|
||||
argsWithProg := os.Args
|
||||
argsWithoutProg := os.Args[1:]
|
||||
|
||||
// `Args` are a slice, you can get individual args
|
||||
// with normal indexing.
|
||||
arg := os.Args[3]
|
||||
|
||||
arg := os.Args[3]
|
||||
|
||||
fmt.Println(argsWithProg)
|
||||
fmt.Println(argsWithoutProg)
|
||||
fmt.Println(arg)
|
||||
fmt.Println(argsWithProg)
|
||||
fmt.Println(argsWithoutProg)
|
||||
fmt.Println(arg)
|
||||
}
|
||||
|
||||
// todo: discuss building before here
|
||||
|
@ -8,11 +8,11 @@ import "fmt"
|
||||
func main() {
|
||||
maxp := flag.Int("repeat", 3, "time to repeat args")
|
||||
flag.Parse()
|
||||
for i := 0; i < *maxp; i++ {
|
||||
for _, arg := range flag.Args() {
|
||||
fmt.Println(arg)
|
||||
}
|
||||
}
|
||||
for i := 0; i < *maxp; i++ {
|
||||
for _, arg := range flag.Args() {
|
||||
fmt.Println(arg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// todo: multiple flags
|
||||
|
@ -1,6 +1,6 @@
|
||||
// ## Environment Variables
|
||||
|
||||
package main
|
||||
package main
|
||||
|
||||
// Use the `os` package to list, set, and get
|
||||
// environment variables.
|
||||
@ -12,15 +12,15 @@ func main() {
|
||||
// `os.Environ` returns a slice of strings in the form
|
||||
// `KEY=value`. You can `strings.Split` them to get
|
||||
// the key and value.
|
||||
for _, e := range os.Environ() {
|
||||
pair := strings.Split(e, "=")
|
||||
fmt.Println(pair[0])
|
||||
for _, e := range os.Environ() {
|
||||
pair := strings.Split(e, "=")
|
||||
fmt.Println(pair[0])
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
// `Setenv` sets a given key, value pair.
|
||||
// `Getenv` returns the value at key, or an empty
|
||||
// string if the key isn't present.
|
||||
os.Setenv("FOO", "bar")
|
||||
fmt.Println(os.Getenv("FOO"))
|
||||
}
|
||||
os.Setenv("FOO", "bar")
|
||||
fmt.Println(os.Getenv("FOO"))
|
||||
}
|
||||
|
@ -6,13 +6,13 @@ import "os/exec"
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
cmd := exec.Command("ls", "-a", "-l")
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("Files:")
|
||||
fmt.Print(string(out))
|
||||
cmd := exec.Command("ls", "-a", "-l")
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("Files:")
|
||||
fmt.Print(string(out))
|
||||
}
|
||||
|
||||
// todo: full command lines with bash
|
||||
|
@ -7,14 +7,14 @@ import "os"
|
||||
import "os/exec"
|
||||
|
||||
func main() {
|
||||
binary, lookErr := exec.LookPath("ls")
|
||||
if lookErr != nil {
|
||||
panic(lookErr)
|
||||
}
|
||||
execErr := syscall.Exec(binary, []string{"-a", "-l", "-h"}, os.Environ())
|
||||
if execErr != nil {
|
||||
panic(execErr)
|
||||
}
|
||||
binary, lookErr := exec.LookPath("ls")
|
||||
if lookErr != nil {
|
||||
panic(lookErr)
|
||||
}
|
||||
execErr := syscall.Exec(binary, []string{"-a", "-l", "-h"}, os.Environ())
|
||||
if execErr != nil {
|
||||
panic(execErr)
|
||||
}
|
||||
}
|
||||
|
||||
// todo: note lack of fork
|
||||
|
@ -2,21 +2,26 @@
|
||||
|
||||
package main
|
||||
|
||||
import ("fmt"; "os"; "os/signal"; "syscall")
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func main() {
|
||||
c := make(chan os.Signal, 1)
|
||||
d := make(chan bool, 1)
|
||||
c := make(chan os.Signal, 1)
|
||||
d := make(chan bool, 1)
|
||||
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
go func(){
|
||||
sig := <- c
|
||||
fmt.Println()
|
||||
fmt.Println(sig)
|
||||
d <- true
|
||||
}()
|
||||
fmt.Println("Awaiting signal")
|
||||
<- d
|
||||
signal.Notify(c, syscall.SIGINT)
|
||||
go func() {
|
||||
sig := <-c
|
||||
fmt.Println()
|
||||
fmt.Println(sig)
|
||||
d <- true
|
||||
}()
|
||||
fmt.Println("Awaiting signal")
|
||||
<-d
|
||||
}
|
||||
|
||||
// todo: sending signals?
|
||||
|
@ -1,16 +1,16 @@
|
||||
// Exit
|
||||
|
||||
package main
|
||||
package main
|
||||
|
||||
// Use `os.Exit` to immediatly exit with a given
|
||||
// status.
|
||||
import "os"
|
||||
import "os"
|
||||
|
||||
func main() {
|
||||
// This `println` will never be reached because the
|
||||
// exit is immediate.
|
||||
defer println("!")
|
||||
os.Exit(3)
|
||||
defer println("!")
|
||||
os.Exit(3)
|
||||
}
|
||||
|
||||
// todo: discuss building before getting here
|
||||
|
@ -7,11 +7,11 @@ import "io/ioutil"
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
resp, err := http.Get("http://127.0.0.1:5000/")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
fmt.Print(string(body))
|
||||
resp, err := http.Get("http://127.0.0.1:5000/")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
fmt.Print(string(body))
|
||||
}
|
||||
|
@ -8,13 +8,15 @@ import "io/ioutil"
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
tr := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}
|
||||
client := &http.Client{Transport: tr}
|
||||
resp, err := client.Get("https://127.0.0.1:5000/")
|
||||
if err != nil { panic(err) }
|
||||
defer resp.Body.Close()
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
fmt.Print(string(body))
|
||||
tr := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}
|
||||
client := &http.Client{Transport: tr}
|
||||
resp, err := client.Get("https://127.0.0.1:5000/")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
fmt.Print(string(body))
|
||||
}
|
||||
|
@ -7,60 +7,70 @@ import "time"
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
// initialize
|
||||
conf := redis.DefaultConfig()
|
||||
client := redis.NewClient(conf)
|
||||
fmt.Println(conf)
|
||||
fmt.Println(client)
|
||||
// initialize
|
||||
conf := redis.DefaultConfig()
|
||||
client := redis.NewClient(conf)
|
||||
fmt.Println(conf)
|
||||
fmt.Println(client)
|
||||
|
||||
// set & get
|
||||
setRep := client.Set("foo", "bar")
|
||||
if setRep.Err != nil { panic(setRep.Err) }
|
||||
fmt.Println(setRep)
|
||||
getRep := client.Get("foo")
|
||||
if getRep.Err != nil { panic(getRep.Err) }
|
||||
getStr, _ := getRep.Str()
|
||||
fmt.Println(getRep)
|
||||
fmt.Println(getStr)
|
||||
// set & get
|
||||
setRep := client.Set("foo", "bar")
|
||||
if setRep.Err != nil {
|
||||
panic(setRep.Err)
|
||||
}
|
||||
fmt.Println(setRep)
|
||||
getRep := client.Get("foo")
|
||||
if getRep.Err != nil {
|
||||
panic(getRep.Err)
|
||||
}
|
||||
getStr, _ := getRep.Str()
|
||||
fmt.Println(getRep)
|
||||
fmt.Println(getStr)
|
||||
|
||||
// varadic calls
|
||||
client.Set("foo1", "bar1")
|
||||
client.Set("foo2", "bar2")
|
||||
client.Set("foo3", "bar3")
|
||||
mgetRep := client.Mget("foo1", "foo2", "foo3")
|
||||
fmt.Println(mgetRep)
|
||||
// varadic calls
|
||||
client.Set("foo1", "bar1")
|
||||
client.Set("foo2", "bar2")
|
||||
client.Set("foo3", "bar3")
|
||||
mgetRep := client.Mget("foo1", "foo2", "foo3")
|
||||
fmt.Println(mgetRep)
|
||||
|
||||
// multi calls
|
||||
mcallRep := client.MultiCall(func(mc *redis.MultiCall) {
|
||||
mc.Set("k1", "v1")
|
||||
mc.Get("k1")
|
||||
})
|
||||
if mcallRep.Err != nil { panic(mcallRep.Err) }
|
||||
mcallVal, _ := mcallRep.Elems[1].Str()
|
||||
fmt.Println(mcallVal)
|
||||
mcallRep := client.MultiCall(func(mc *redis.MultiCall) {
|
||||
mc.Set("k1", "v1")
|
||||
mc.Get("k1")
|
||||
})
|
||||
if mcallRep.Err != nil {
|
||||
panic(mcallRep.Err)
|
||||
}
|
||||
mcallVal, _ := mcallRep.Elems[1].Str()
|
||||
fmt.Println(mcallVal)
|
||||
|
||||
// transactional calls
|
||||
tranRep := client.Transaction(func(mc *redis.MultiCall) {
|
||||
mc.Set("k2", "v2")
|
||||
mc.Get("k2")
|
||||
})
|
||||
if tranRep.Err != nil { panic(tranRep.Err) }
|
||||
tranStr, _ := tranRep.Elems[1].Str()
|
||||
fmt.Println(tranStr)
|
||||
// transactional calls
|
||||
tranRep := client.Transaction(func(mc *redis.MultiCall) {
|
||||
mc.Set("k2", "v2")
|
||||
mc.Get("k2")
|
||||
})
|
||||
if tranRep.Err != nil {
|
||||
panic(tranRep.Err)
|
||||
}
|
||||
tranStr, _ := tranRep.Elems[1].Str()
|
||||
fmt.Println(tranStr)
|
||||
|
||||
// pubsub
|
||||
msgHdlr := func(msg *redis.Message) {
|
||||
fmt.Println(msg)
|
||||
}
|
||||
sub, subErr := client.Subscription(msgHdlr)
|
||||
if subErr != nil { panic(subErr) }
|
||||
defer sub.Close()
|
||||
sub.Subscribe("chan1", "chan2")
|
||||
sub.Psubscribe("chan*")
|
||||
client.Publish("chan1", "foo")
|
||||
sub.Unsubscribe("chan1")
|
||||
client.Publish("chan2", "bar")
|
||||
time.Sleep(time.Second)
|
||||
// pubsub
|
||||
msgHdlr := func(msg *redis.Message) {
|
||||
fmt.Println(msg)
|
||||
}
|
||||
sub, subErr := client.Subscription(msgHdlr)
|
||||
if subErr != nil {
|
||||
panic(subErr)
|
||||
}
|
||||
defer sub.Close()
|
||||
sub.Subscribe("chan1", "chan2")
|
||||
sub.Psubscribe("chan*")
|
||||
client.Publish("chan1", "foo")
|
||||
sub.Unsubscribe("chan1")
|
||||
client.Publish("chan2", "bar")
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
|
||||
// todo: connection pooling & concurrency?
|
||||
|
@ -8,46 +8,60 @@ import "time"
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
db, openErr := sql.Open("postgres", "dbname=gobyexample sslmode=disable")
|
||||
if openErr != nil { panic(openErr) }
|
||||
defer db.Close()
|
||||
fmt.Println(db)
|
||||
|
||||
createRep, createErr := db.Exec("CREATE TABLE items (a int, b float, c boolean, d text, e timestamp with time zone)")
|
||||
if createErr != nil { panic(createErr) }
|
||||
fmt.Println(createRep)
|
||||
|
||||
insertRep, insertErr := db.Exec("INSERT INTO items VALUES (1, 2.0, false, 'string', '2000-01-01T01:02:03Z')")
|
||||
if insertErr != nil { panic(insertErr) }
|
||||
fmt.Println(insertRep)
|
||||
|
||||
t1, _ := time.Parse(time.RFC3339, "2000-04-08T03:02:01Z")
|
||||
t2, _ := time.Parse(time.RFC3339, "2007-03-02T10:15:45Z")
|
||||
minsertRep, minsertErr := db.Exec("Insert INTO items VALUES ($1, $2, $3, $4, $5), ($6, $7, $8, $9, $10)",
|
||||
3, 7.0, true, "more", t1,
|
||||
5, 1.0, false, "less", t2)
|
||||
if minsertErr != nil { panic(minsertErr) }
|
||||
num, _ := minsertRep.RowsAffected()
|
||||
fmt.Println(num)
|
||||
|
||||
rows, selectErr := db.Query("SELECT * FROM items")
|
||||
if selectErr != nil { panic(selectErr) }
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var r1 int
|
||||
var r2 float64
|
||||
var r3 bool
|
||||
var r4 string
|
||||
var r5 time.Time
|
||||
rows.Scan(&r1, &r2, &r3, &r4, &r5)
|
||||
fmt.Println(r1, r2, r3, r4, r5)
|
||||
db, openErr := sql.Open("postgres", "dbname=gobyexample sslmode=disable")
|
||||
if openErr != nil {
|
||||
panic(openErr)
|
||||
}
|
||||
rowsErr := rows.Err()
|
||||
if rowsErr != nil { panic(rowsErr) }
|
||||
|
||||
dropRep, dropErr := db.Exec("DROP TABLE items")
|
||||
if dropErr != nil { panic(dropErr) }
|
||||
fmt.Println(dropRep)
|
||||
defer db.Close()
|
||||
fmt.Println(db)
|
||||
|
||||
createRep, createErr := db.Exec("CREATE TABLE items (a int, b float, c boolean, d text, e timestamp with time zone)")
|
||||
if createErr != nil {
|
||||
panic(createErr)
|
||||
}
|
||||
fmt.Println(createRep)
|
||||
|
||||
insertRep, insertErr := db.Exec("INSERT INTO items VALUES (1, 2.0, false, 'string', '2000-01-01T01:02:03Z')")
|
||||
if insertErr != nil {
|
||||
panic(insertErr)
|
||||
}
|
||||
fmt.Println(insertRep)
|
||||
|
||||
t1, _ := time.Parse(time.RFC3339, "2000-04-08T03:02:01Z")
|
||||
t2, _ := time.Parse(time.RFC3339, "2007-03-02T10:15:45Z")
|
||||
minsertRep, minsertErr := db.Exec("Insert INTO items VALUES ($1, $2, $3, $4, $5), ($6, $7, $8, $9, $10)",
|
||||
3, 7.0, true, "more", t1,
|
||||
5, 1.0, false, "less", t2)
|
||||
if minsertErr != nil {
|
||||
panic(minsertErr)
|
||||
}
|
||||
num, _ := minsertRep.RowsAffected()
|
||||
fmt.Println(num)
|
||||
|
||||
rows, selectErr := db.Query("SELECT * FROM items")
|
||||
if selectErr != nil {
|
||||
panic(selectErr)
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var r1 int
|
||||
var r2 float64
|
||||
var r3 bool
|
||||
var r4 string
|
||||
var r5 time.Time
|
||||
rows.Scan(&r1, &r2, &r3, &r4, &r5)
|
||||
fmt.Println(r1, r2, r3, r4, r5)
|
||||
}
|
||||
rowsErr := rows.Err()
|
||||
if rowsErr != nil {
|
||||
panic(rowsErr)
|
||||
}
|
||||
|
||||
dropRep, dropErr := db.Exec("DROP TABLE items")
|
||||
if dropErr != nil {
|
||||
panic(dropErr)
|
||||
}
|
||||
fmt.Println(dropRep)
|
||||
}
|
||||
|
||||
// todo: connection pooling & concurrency
|
||||
|
@ -5,21 +5,23 @@ package main
|
||||
import "net/smtp"
|
||||
|
||||
func main() {
|
||||
auth := smtp.PlainAuth(
|
||||
"",
|
||||
"mark@heroku.com",
|
||||
"xxx",
|
||||
"smtp.gmail.com",
|
||||
)
|
||||
auth := smtp.PlainAuth(
|
||||
"",
|
||||
"mark@heroku.com",
|
||||
"xxx",
|
||||
"smtp.gmail.com",
|
||||
)
|
||||
|
||||
err := smtp.SendMail(
|
||||
"smtp.gmail.com:25",
|
||||
auth,
|
||||
"mark+sent@heroku.com",
|
||||
[]string{"mark@heroku.com"},
|
||||
[]byte("nThe body."),
|
||||
)
|
||||
if err != nil { panic(err) }
|
||||
err := smtp.SendMail(
|
||||
"smtp.gmail.com:25",
|
||||
auth,
|
||||
"mark+sent@heroku.com",
|
||||
[]string{"mark@heroku.com"},
|
||||
[]byte("nThe body."),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// todo: missing subject, cc, bcc
|
||||
|
@ -6,7 +6,7 @@ import "net/http"
|
||||
|
||||
func hello(res http.ResponseWriter, req *http.Request) {
|
||||
res.Header().Set("Content-Type", "text/plain")
|
||||
res.Write([]byte("Hello web\n"))
|
||||
res.Write([]byte("Hello web\n"))
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
@ -6,13 +6,13 @@ import "net/http"
|
||||
import "fmt"
|
||||
|
||||
func hello(res http.ResponseWriter, req *http.Request) {
|
||||
res.Header().Set("Content-Type", "text/plain")
|
||||
if req.URL.Path == "/protected" {
|
||||
res.WriteHeader(401)
|
||||
fmt.Fprintln(res, "Not allowed")
|
||||
} else {
|
||||
fmt.Fprintln(res, "Hello")
|
||||
}
|
||||
res.Header().Set("Content-Type", "text/plain")
|
||||
if req.URL.Path == "/protected" {
|
||||
res.WriteHeader(401)
|
||||
fmt.Fprintln(res, "Not allowed")
|
||||
} else {
|
||||
fmt.Fprintln(res, "Hello")
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
@ -7,13 +7,13 @@ import "net/http"
|
||||
import "fmt"
|
||||
|
||||
func hello(w http.ResponseWriter, req *http.Request) {
|
||||
fmt.Fprintln(w, "hello " + req.URL.Query().Get(":name"))
|
||||
fmt.Fprintln(w, "hello "+req.URL.Query().Get(":name"))
|
||||
}
|
||||
|
||||
func main() {
|
||||
p := pat.New()
|
||||
p.Get("/hello/:name", http.HandlerFunc(hello))
|
||||
http.ListenAndServe(":5000", p)
|
||||
p := pat.New()
|
||||
p.Get("/hello/:name", http.HandlerFunc(hello))
|
||||
http.ListenAndServe(":5000", p)
|
||||
}
|
||||
|
||||
// todo: consider gorilla-web
|
||||
|
@ -7,32 +7,32 @@ import "time"
|
||||
import "fmt"
|
||||
|
||||
func runLogging(logs chan string) {
|
||||
for log := range logs {
|
||||
fmt.Println(log)
|
||||
}
|
||||
for log := range logs {
|
||||
fmt.Println(log)
|
||||
}
|
||||
}
|
||||
|
||||
func wrapLogging(f http.HandlerFunc) http.HandlerFunc {
|
||||
logs := make(chan string, 10000)
|
||||
go runLogging(logs)
|
||||
return func(res http.ResponseWriter, req *http.Request) {
|
||||
start := time.Now()
|
||||
f(res, req)
|
||||
method := req.Method
|
||||
path := req.URL.Path
|
||||
elapsed := float64(time.Since(start)) / 1000000.0
|
||||
logs <- fmt.Sprintf("method=%s path=%s elapsed=%f", method, path, elapsed)
|
||||
}
|
||||
logs := make(chan string, 10000)
|
||||
go runLogging(logs)
|
||||
return func(res http.ResponseWriter, req *http.Request) {
|
||||
start := time.Now()
|
||||
f(res, req)
|
||||
method := req.Method
|
||||
path := req.URL.Path
|
||||
elapsed := float64(time.Since(start)) / 1000000.0
|
||||
logs <- fmt.Sprintf("method=%s path=%s elapsed=%f", method, path, elapsed)
|
||||
}
|
||||
}
|
||||
|
||||
func hello(res http.ResponseWriter, req *http.Request) {
|
||||
res.Header().Set("Content-Type", "text/plain")
|
||||
time.Sleep(time.Millisecond * 50)
|
||||
fmt.Fprintln(res, "Hello logged world")
|
||||
time.Sleep(time.Millisecond * 50)
|
||||
fmt.Fprintln(res, "Hello logged world")
|
||||
}
|
||||
|
||||
func main() {
|
||||
handler := wrapLogging(hello)
|
||||
handler := wrapLogging(hello)
|
||||
http.HandleFunc("/", handler)
|
||||
http.ListenAndServe(":5000", nil)
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ package main
|
||||
import "net/http"
|
||||
|
||||
func main() {
|
||||
handler := http.FileServer(http.Dir("./"))
|
||||
http.ListenAndServe(":5000", handler)
|
||||
handler := http.FileServer(http.Dir("./"))
|
||||
http.ListenAndServe(":5000", handler)
|
||||
}
|
||||
|
||||
// todo: index pages
|
||||
|
@ -3,44 +3,44 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"encoding/base64"
|
||||
"strings"
|
||||
"fmt"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Authenticator func(string, string) bool
|
||||
|
||||
func testAuth(r *http.Request, auth Authenticator) bool {
|
||||
s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
|
||||
if len(s) != 2 || s[0] != "Basic" {
|
||||
return false
|
||||
}
|
||||
b, err := base64.StdEncoding.DecodeString(s[1])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
pair := strings.SplitN(string(b), ":", 2)
|
||||
if len(pair) != 2 {
|
||||
return false
|
||||
}
|
||||
return auth(pair[0], pair[1])
|
||||
s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
|
||||
if len(s) != 2 || s[0] != "Basic" {
|
||||
return false
|
||||
}
|
||||
b, err := base64.StdEncoding.DecodeString(s[1])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
pair := strings.SplitN(string(b), ":", 2)
|
||||
if len(pair) != 2 {
|
||||
return false
|
||||
}
|
||||
return auth(pair[0], pair[1])
|
||||
}
|
||||
|
||||
func requireAuth(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("WWW-Authenticate", `Basic realm="private"`)
|
||||
w.WriteHeader(401)
|
||||
w.Write([]byte("401 Unauthorized\n"))
|
||||
w.Header().Set("WWW-Authenticate", `Basic realm="private"`)
|
||||
w.WriteHeader(401)
|
||||
w.Write([]byte("401 Unauthorized\n"))
|
||||
}
|
||||
|
||||
func wrapAuth(h http.HandlerFunc, a Authenticator) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if testAuth(r, a) {
|
||||
h(w, r)
|
||||
} else {
|
||||
requireAuth(w, r)
|
||||
}
|
||||
}
|
||||
if testAuth(r, a) {
|
||||
h(w, r)
|
||||
} else {
|
||||
requireAuth(w, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func hello(w http.ResponseWriter, r *http.Request) {
|
||||
@ -48,10 +48,10 @@ func hello(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func main() {
|
||||
checkPassword := func(_, password string) bool {
|
||||
return password == "supersecret"
|
||||
}
|
||||
handler1 := http.HanderFunc(hello)
|
||||
handler2 := wrapAuth(handler1, checkPassword)
|
||||
checkPassword := func(_, password string) bool {
|
||||
return password == "supersecret"
|
||||
}
|
||||
handler1 := http.HanderFunc(hello)
|
||||
handler2 := wrapAuth(handler1, checkPassword)
|
||||
http.ListenAndServe(":5000", handler2)
|
||||
}
|
||||
|
@ -8,26 +8,26 @@ import "fmt"
|
||||
|
||||
func hello(res http.ResponseWriter, req *http.Request) {
|
||||
res.Header().Set("Content-Type", "text/plain")
|
||||
fmt.Fprintln(res, "Hello canonical world")
|
||||
fmt.Fprintln(res, "Hello canonical world")
|
||||
}
|
||||
|
||||
func wrapCanonicalHost(f http.HandlerFunc, canonicalHost string) http.HandlerFunc {
|
||||
return func(res http.ResponseWriter, req *http.Request) {
|
||||
hostPort := strings.Split(req.Host, ":")
|
||||
host := hostPort[0]
|
||||
if host != canonicalHost {
|
||||
fmt.Println("redirecting from", host, "to", canonicalHost)
|
||||
hostPort[0] = canonicalHost
|
||||
url := "http://" + strings.Join(hostPort, ":") + req.URL.String()
|
||||
http.Redirect(res, req, url, 301)
|
||||
return
|
||||
}
|
||||
f(res, req)
|
||||
}
|
||||
return func(res http.ResponseWriter, req *http.Request) {
|
||||
hostPort := strings.Split(req.Host, ":")
|
||||
host := hostPort[0]
|
||||
if host != canonicalHost {
|
||||
fmt.Println("redirecting from", host, "to", canonicalHost)
|
||||
hostPort[0] = canonicalHost
|
||||
url := "http://" + strings.Join(hostPort, ":") + req.URL.String()
|
||||
http.Redirect(res, req, url, 301)
|
||||
return
|
||||
}
|
||||
f(res, req)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
handler := wrapCanonicalHost(hello, "localhost")
|
||||
handler := wrapCanonicalHost(hello, "localhost")
|
||||
http.HandleFunc("/", handler)
|
||||
http.ListenAndServe(":5000", nil)
|
||||
}
|
||||
|
@ -7,19 +7,19 @@ import "fmt"
|
||||
|
||||
func hello(res http.ResponseWriter, req *http.Request) {
|
||||
res.Header().Set("Content-Type", "text/plain")
|
||||
fmt.Fprintln(res, "Hello wrapped world")
|
||||
fmt.Fprintln(res, "Hello wrapped world")
|
||||
}
|
||||
|
||||
func wrapMiddleware(f http.HandlerFunc) http.HandlerFunc {
|
||||
return func(res http.ResponseWriter, req *http.Request) {
|
||||
fmt.Println("before")
|
||||
f(res, req)
|
||||
fmt.Println("after")
|
||||
}
|
||||
return func(res http.ResponseWriter, req *http.Request) {
|
||||
fmt.Println("before")
|
||||
f(res, req)
|
||||
fmt.Println("after")
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
handler := wrapMiddleware(hello)
|
||||
handler := wrapMiddleware(hello)
|
||||
http.HandleFunc("/", handler)
|
||||
http.ListenAndServe(":5000", nil)
|
||||
}
|
||||
|
@ -3,88 +3,92 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
func slow(res http.ResponseWriter, req *http.Request) {
|
||||
fmt.Println("respond at=start")
|
||||
time.Sleep(time.Second * 5)
|
||||
res.Header().Set("Content-Type", "text/plain")
|
||||
fmt.Fprintln(res, "Finally.")
|
||||
fmt.Println("respond at=finish")
|
||||
fmt.Println("respond at=start")
|
||||
time.Sleep(time.Second * 5)
|
||||
res.Header().Set("Content-Type", "text/plain")
|
||||
fmt.Fprintln(res, "Finally.")
|
||||
fmt.Println("respond at=finish")
|
||||
}
|
||||
|
||||
var connCount int64 = 0
|
||||
|
||||
type watchedConn struct {
|
||||
net.Conn
|
||||
net.Conn
|
||||
}
|
||||
|
||||
func (w *watchedConn) Close() error {
|
||||
atomic.AddInt64(&connCount, -1)
|
||||
return w.Conn.Close()
|
||||
atomic.AddInt64(&connCount, -1)
|
||||
return w.Conn.Close()
|
||||
}
|
||||
|
||||
type watchedListener struct {
|
||||
net.Listener
|
||||
net.Listener
|
||||
}
|
||||
|
||||
func (l *watchedListener) Accept() (net.Conn, error) {
|
||||
conn, err := l.Listener.Accept()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
atomic.AddInt64(&connCount, 1)
|
||||
return &watchedConn{Conn: conn}, nil
|
||||
conn, err := l.Listener.Accept()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
atomic.AddInt64(&connCount, 1)
|
||||
return &watchedConn{Conn: conn}, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
stop := make(chan bool, 1)
|
||||
sig := make(chan os.Signal, 1)
|
||||
|
||||
server := &http.Server{Handler: http.HandlerFunc(slow)}
|
||||
fmt.Println("listen at=start")
|
||||
listener, listenErr := net.Listen("tcp", ":5000")
|
||||
if listenErr != nil { panic(listenErr) }
|
||||
wListener := &watchedListener{Listener: listener}
|
||||
fmt.Println("listen at=finish")
|
||||
stop := make(chan bool, 1)
|
||||
sig := make(chan os.Signal, 1)
|
||||
|
||||
go func() {
|
||||
<- stop
|
||||
fmt.Println("close at=start")
|
||||
closeErr := wListener.Close()
|
||||
if closeErr != nil { panic(closeErr) }
|
||||
fmt.Println("close at=finish")
|
||||
}()
|
||||
server := &http.Server{Handler: http.HandlerFunc(slow)}
|
||||
fmt.Println("listen at=start")
|
||||
listener, listenErr := net.Listen("tcp", ":5000")
|
||||
if listenErr != nil {
|
||||
panic(listenErr)
|
||||
}
|
||||
wListener := &watchedListener{Listener: listener}
|
||||
fmt.Println("listen at=finish")
|
||||
|
||||
go func() {
|
||||
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
|
||||
fmt.Println("trap at=start")
|
||||
<- sig
|
||||
stop <- true
|
||||
fmt.Println("trap at=finish")
|
||||
}()
|
||||
go func() {
|
||||
<-stop
|
||||
fmt.Println("close at=start")
|
||||
closeErr := wListener.Close()
|
||||
if closeErr != nil {
|
||||
panic(closeErr)
|
||||
}
|
||||
fmt.Println("close at=finish")
|
||||
}()
|
||||
|
||||
fmt.Println("serve at=start")
|
||||
server.Serve(wListener)
|
||||
fmt.Println("serve at=finish")
|
||||
for {
|
||||
connCountCurrent := atomic.LoadInt64(&connCount)
|
||||
if connCountCurrent > 0 {
|
||||
fmt.Println("wait at=pending remaining=", connCountCurrent)
|
||||
time.Sleep(time.Second)
|
||||
} else {
|
||||
fmt.Println("wait at=finish remaining=", connCountCurrent)
|
||||
return
|
||||
}
|
||||
}
|
||||
go func() {
|
||||
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
|
||||
fmt.Println("trap at=start")
|
||||
<-sig
|
||||
stop <- true
|
||||
fmt.Println("trap at=finish")
|
||||
}()
|
||||
|
||||
fmt.Println("serve at=start")
|
||||
server.Serve(wListener)
|
||||
fmt.Println("serve at=finish")
|
||||
for {
|
||||
connCountCurrent := atomic.LoadInt64(&connCount)
|
||||
if connCountCurrent > 0 {
|
||||
fmt.Println("wait at=pending remaining=", connCountCurrent)
|
||||
time.Sleep(time.Second)
|
||||
} else {
|
||||
fmt.Println("wait at=finish remaining=", connCountCurrent)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// todo: clean up logging
|
||||
|
@ -1,29 +1,29 @@
|
||||
// ## SHA1 Hashes
|
||||
|
||||
package main
|
||||
|
||||
|
||||
package main
|
||||
|
||||
// Package `crypto/sha1` computes SHA1 hashes.
|
||||
import "crypto/sha1"
|
||||
import "encoding/hex"
|
||||
import "crypto/sha1"
|
||||
import "encoding/hex"
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
|
||||
func main() {
|
||||
// The pattern is `sha1.New()`, `sha1.Write(bytes)`,
|
||||
// then `sha1.Sum([]byte{})
|
||||
h := sha1.New()
|
||||
|
||||
h := sha1.New()
|
||||
|
||||
// `Write` expects bytes. If you have a string `s`
|
||||
// use `[]byte(s)` to coerce it.
|
||||
h.Write([]byte("sha1 this string"))
|
||||
|
||||
h.Write([]byte("sha1 this string"))
|
||||
|
||||
// Get the result. The argument to `Sum` can be used
|
||||
// to append to an existing buffer: usually uneeded.
|
||||
bs := h.Sum(nil)
|
||||
|
||||
bs := h.Sum(nil)
|
||||
|
||||
// SHA1 values are often printed in hex, for example
|
||||
// with git.
|
||||
fmt.Println(hex.EncodeToString(bs))
|
||||
}
|
||||
fmt.Println(hex.EncodeToString(bs))
|
||||
}
|
||||
|
||||
// You can compute other hashes using a similar
|
||||
// pattern. For exmpale, to compute MD5 hashes
|
||||
|
@ -5,12 +5,14 @@ package main
|
||||
import "net/http"
|
||||
|
||||
func handler(res http.ResponseWriter, req *http.Request) {
|
||||
res.Header().Set("Content-Type", "text/plain")
|
||||
res.Write([]byte("Hello from HTTPS\n"))
|
||||
res.Header().Set("Content-Type", "text/plain")
|
||||
res.Write([]byte("Hello from HTTPS\n"))
|
||||
}
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/", handler)
|
||||
err := http.ListenAndServeTLS(":5000", "/tmp/server.crt", "/tmp/server.key", nil)
|
||||
if err != nil { panic(err) }
|
||||
http.HandleFunc("/", handler)
|
||||
err := http.ListenAndServeTLS(":5000", "/tmp/server.crt", "/tmp/server.key", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
@ -6,14 +6,14 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"regexp"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func minInt(a, b int) int {
|
||||
if (a < b) {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
@ -24,7 +24,9 @@ func main() {
|
||||
sourceNames := make([]string, 0)
|
||||
sourceMap := make(map[string]string)
|
||||
fileInfos, dirErr := ioutil.ReadDir("./")
|
||||
if dirErr != nil { panic(dirErr) }
|
||||
if dirErr != nil {
|
||||
panic(dirErr)
|
||||
}
|
||||
baseTrimmer, _ := regexp.Compile("[0-9x]+-")
|
||||
for _, fi := range fileInfos {
|
||||
baseName := baseTrimmer.ReplaceAllString(fi.Name(), "")
|
||||
@ -36,15 +38,17 @@ func main() {
|
||||
|
||||
// read names from index
|
||||
indexBytes, idxErr := ioutil.ReadFile("tool/index.txt")
|
||||
if idxErr != nil { panic (idxErr) }
|
||||
if idxErr != nil {
|
||||
panic(idxErr)
|
||||
}
|
||||
indexNamesAll := strings.Split(string(indexBytes), "\n")
|
||||
indexNames := make([]string, 0)
|
||||
for _, indexName := range indexNamesAll {
|
||||
if indexName != "" && !strings.Contains(indexName, "#") && !strings.Contains(indexName, "~") {
|
||||
if indexName != "" && !strings.Contains(indexName, "#") && !strings.Contains(indexName, "~") {
|
||||
indexNames = append(indexNames, indexName)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// sanity check two lists
|
||||
if len(sourceNames) != len(indexNames) {
|
||||
sort.Strings(sourceNames)
|
||||
@ -54,7 +58,7 @@ func main() {
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
||||
// rename some stuff
|
||||
for index, indexName := range indexNames {
|
||||
oldName := sourceMap[indexName]
|
||||
|
Loading…
x
Reference in New Issue
Block a user