gofmt wat u know about it

This commit is contained in:
Mark McGranaghan 2012-09-23 18:31:33 -07:00
parent f93bdba75c
commit 89f95f2ac5
66 changed files with 729 additions and 678 deletions

View File

@ -6,6 +6,6 @@ import "fmt"
func main() { func main() {
// `x := val` is shorthand for `var x type = val`. // `x := val` is shorthand for `var x type = val`.
x := "Hello assignment" x := "Hello assignment"
fmt.Println(x) fmt.Println(x)
} }

View File

@ -5,8 +5,8 @@ package main
import "fmt" import "fmt"
func main() { func main() {
var x [5]int var x [5]int
x[4] = 100 x[4] = 100
fmt.Println(x) fmt.Println(x)
fmt.Println(x[4]) fmt.Println(x[4])
} }

View File

@ -5,12 +5,12 @@ package main
import "fmt" import "fmt"
func main() { func main() {
slice1 := []int{1,2,3} slice1 := []int{1, 2, 3}
slice2 := append(slice1, 4, 5) slice2 := append(slice1, 4, 5)
fmt.Println(slice1) fmt.Println(slice1)
fmt.Println(slice2) fmt.Println(slice2)
slice3 := make([]int, 2) slice3 := make([]int, 2)
copy(slice3, slice1) copy(slice3, slice1)
fmt.Println(slice1) fmt.Println(slice1)
fmt.Println(slice3) fmt.Println(slice3)
} }

View File

@ -5,16 +5,16 @@ package main
import "fmt" import "fmt"
func main() { func main() {
x := make(map[string]int) x := make(map[string]int)
x["this"] = 7 x["this"] = 7
x["that"] = 13 x["that"] = 13
fmt.Println(x) fmt.Println(x)
fmt.Println(x["this"]) fmt.Println(x["this"])
fmt.Println(x["missing"]) fmt.Println(x["missing"])
fmt.Println(len(x)) fmt.Println(len(x))
delete(x, "that") delete(x, "that")
fmt.Println(x["that"]) fmt.Println(x["that"])
fmt.Println(len(x)) fmt.Println(len(x))
_, present := x["that"] _, present := x["that"]
fmt.Println(present) fmt.Println(present)
} }

View File

@ -5,16 +5,16 @@ package main
import "fmt" import "fmt"
func avg(vals []float64) float64 { func avg(vals []float64) float64 {
total := 0.0 total := 0.0
for _, val := range vals { for _, val := range vals {
total += val total += val
} }
return total / float64(len(vals)) return total / float64(len(vals))
} }
func main() { func main() {
input := []float64{98,93,77,82,83} input := []float64{98, 93, 77, 82, 83}
fmt.Println(input) fmt.Println(input)
output := avg(input) output := avg(input)
fmt.Println(output) fmt.Println(output)
} }

View File

@ -12,5 +12,5 @@ func factorial(x uint) uint {
} }
func main() { func main() {
fmt.Println(factorial(7)) fmt.Println(factorial(7))
} }

View File

@ -9,5 +9,5 @@ func main() {
// We'll use panic throught this book to check for // We'll use panic throught this book to check for
// unexpected errors. This is the only program in the // unexpected errors. This is the only program in the
// book designed to panic. // book designed to panic.
panic("O noes") panic("O noes")
} }

View File

@ -9,8 +9,8 @@ func one(xPtr *int) {
} }
func main() { func main() {
xPtr := new(int) xPtr := new(int)
fmt.Println(xPtr) fmt.Println(xPtr)
fmt.Println(*xPtr) fmt.Println(*xPtr)
one(xPtr) one(xPtr)
fmt.Println(xPtr) fmt.Println(xPtr)
fmt.Println(*xPtr) fmt.Println(*xPtr)

View File

@ -9,16 +9,16 @@ type Circle struct {
} }
func main() { func main() {
cEmptyPtr := new(Circle) cEmptyPtr := new(Circle)
fmt.Println(cEmptyPtr) fmt.Println(cEmptyPtr)
fmt.Println(*cEmptyPtr) fmt.Println(*cEmptyPtr)
cValue := Circle{x: 1, y: 2, r: 5} cValue := Circle{x: 1, y: 2, r: 5}
fmt.Println(&cValue) fmt.Println(&cValue)
fmt.Println(cValue) fmt.Println(cValue)
cOrdered := Circle{1, 2, 5} cOrdered := Circle{1, 2, 5}
fmt.Println(cOrdered) fmt.Println(cOrdered)
} }
// todo: add field access // todo: add field access

View File

@ -10,7 +10,7 @@ type Circle struct {
} }
func (c *Circle) area() float64 { func (c *Circle) area() float64 {
return math.Pi * c.r*c.r return math.Pi * c.r * c.r
} }
type Rectangle struct { type Rectangle struct {
@ -30,10 +30,10 @@ func (r *Rectangle) area() float64 {
} }
func main() { func main() {
circle := Circle{x: 0, y: 3, r: 5} circle := Circle{x: 0, y: 3, r: 5}
fmt.Println(circle.area()) fmt.Println(circle.area())
rectangle := Rectangle {x1: 3, x2: 10, y1: 5, y2: 7} rectangle := Rectangle{x1: 3, x2: 10, y1: 5, y2: 7}
fmt.Println(rectangle.area()) fmt.Println(rectangle.area())
} }
// todo: pointer vs value receivers // todo: pointer vs value receivers

View File

@ -14,7 +14,7 @@ type Circle struct {
} }
func (c *Circle) area() float64 { func (c *Circle) area() float64 {
return math.Pi * c.r*c.r return math.Pi * c.r * c.r
} }
type Rectangle struct { type Rectangle struct {
@ -42,14 +42,14 @@ func totalArea(shapes ...Shape) float64 {
} }
func main() { func main() {
circle := Circle{x: 0, y: 3, r: 5} circle := Circle{x: 0, y: 3, r: 5}
rectangle := Rectangle {x1: 3, x2: 10, y1: 5, y2: 7} rectangle := Rectangle{x1: 3, x2: 10, y1: 5, y2: 7}
area := 0.0 area := 0.0
for _, s := range []Shape{&circle, &rectangle} { for _, s := range []Shape{&circle, &rectangle} {
area += s.area() area += s.area()
} }
fmt.Println(area) fmt.Println(area)
} }
// todo: is this named wrong? // todo: is this named wrong?

View File

@ -2,22 +2,25 @@
package main package main
import ("fmt"; "errors") import (
"errors"
"fmt"
)
func myFun(arg int) (int, error) { func myFun(arg int) (int, error) {
if arg == 42 { if arg == 42 {
return -1, errors.New("Can't work with 42") return -1, errors.New("Can't work with 42")
} }
return arg + 3, nil return arg + 3, nil
} }
func main() { func main() {
r, _ := myFun(7) r, _ := myFun(7)
fmt.Println(r) fmt.Println(r)
_, e := myFun(42) _, e := myFun(42)
fmt.Println(e) fmt.Println(e)
} }
// todo: custom errors // todo: custom errors

View File

@ -5,18 +5,18 @@ package main
import "fmt" import "fmt"
func main() { func main() {
x := make(map[string]string) x := make(map[string]string)
x["here"] = "yes" x["here"] = "yes"
if name, ok := x["?"]; ok { if name, ok := x["?"]; ok {
fmt.Println(name) fmt.Println(name)
} else { } else {
fmt.Println("miss") fmt.Println("miss")
} }
if name, ok := x["here"]; ok { if name, ok := x["here"]; ok {
fmt.Println(name) fmt.Println(name)
} }
} }
// todo: note about use with errors // todo: note about use with errors

View File

@ -9,18 +9,18 @@ import "fmt"
func f(n int) { func f(n int) {
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
fmt.Println(n, ":", 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() { func main() {
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
f(i) f(i)
} }
fmt.Println() fmt.Println()
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
go f(i) go f(i)
} }
var input string var input string
fmt.Scanln(&input) fmt.Scanln(&input)
} }

View File

@ -6,7 +6,7 @@ import "fmt"
func main() { func main() {
var messages chan string = make(chan string) var messages chan string = make(chan string)
go func() { messages <- "ping"}() go func() { messages <- "ping" }()
msg := <- messages msg := <-messages
fmt.Println(msg) fmt.Println(msg)
} }

View File

@ -7,6 +7,6 @@ import "fmt"
func main() { func main() {
var messages chan string = make(chan string, 1) var messages chan string = make(chan string, 1)
messages <- "ping" messages <- "ping"
msg := <- messages msg := <-messages
fmt.Println(msg) fmt.Println(msg)
} }

View File

@ -12,14 +12,14 @@ func pinger(pings chan<- string) {
func ponger(pings <-chan string, pongs chan<- string) { func ponger(pings <-chan string, pongs chan<- string) {
for { for {
<- pings <-pings
pongs <- "pong" pongs <- "pong"
} }
} }
func printer(pongs <-chan string) { func printer(pongs <-chan string) {
for { for {
msg := <- pongs msg := <-pongs
fmt.Println(msg) fmt.Println(msg)
} }
} }
@ -32,6 +32,6 @@ func main() {
go ponger(pings, pongs) go ponger(pings, pongs)
go printer(pongs) go printer(pongs)
var input string var input string
fmt.Scanln(&input) fmt.Scanln(&input)
} }

View File

@ -28,5 +28,5 @@ func main() {
// Block until we can receive a value from the worker // Block until we can receive a value from the worker
// over the channel. // over the channel.
<- done <-done
} }

View File

@ -8,27 +8,27 @@ import "fmt"
func main() { func main() {
c1 := make(chan string) c1 := make(chan string)
c2 := make(chan string) c2 := make(chan string)
d := make(chan bool, 1) d := make(chan bool, 1)
go func() { go func() {
time.Sleep(time.Second * 1) time.Sleep(time.Second * 1)
c1 <- "from 1" c1 <- "from 1"
}() }()
go func() { go func() {
time.Sleep(time.Second * 2) time.Sleep(time.Second * 2)
c2 <- "from 2" c2 <- "from 2"
}() }()
go func() { go func() {
for i :=0; i < 2; i ++ { for i := 0; i < 2; i++ {
select { select {
case msg1 := <- c1: case msg1 := <-c1:
fmt.Println(msg1) fmt.Println(msg1)
case msg2 := <- c2: case msg2 := <-c2:
fmt.Println(msg2) fmt.Println(msg2)
} }
} }
d <- true d <- true
}() }()
<- d <-d
} }

View File

@ -7,21 +7,21 @@ import "fmt"
func main() { func main() {
c := make(chan string) c := make(chan string)
d := make(chan bool, 1) d := make(chan bool, 1)
go func() { go func() {
time.Sleep(time.Millisecond * 1500) time.Sleep(time.Millisecond * 1500)
c <- "ready" c <- "ready"
}() }()
go func() { go func() {
select { select {
case msg := <- c: case msg := <-c:
fmt.Println(msg) fmt.Println(msg)
case <- time.After(time.Millisecond * 1000): case <-time.After(time.Millisecond * 1000):
fmt.Println("timeout") fmt.Println("timeout")
} }
d <- true d <- true
}() }()
<- d <-d
} }

View File

@ -8,19 +8,19 @@ import "math/rand"
import "fmt" import "fmt"
func main() { func main() {
times := new([20]int) times := new([20]int)
wait := new(sync.WaitGroup) wait := new(sync.WaitGroup)
for i := 0; i < 20; i++ { for i := 0; i < 20; i++ {
n := i n := i
wait.Add(1) wait.Add(1)
go func() { go func() {
opTime := rand.Intn(2000) opTime := rand.Intn(2000)
time.Sleep(time.Duration(opTime) * time.Millisecond) time.Sleep(time.Duration(opTime) * time.Millisecond)
fmt.Println(n) fmt.Println(n)
times[n] = opTime times[n] = opTime
wait.Done() wait.Done()
}() }()
} }
wait.Wait() wait.Wait()
fmt.Println(*times) fmt.Println(*times)
} }

View File

@ -5,10 +5,10 @@ import "time"
import "fmt" import "fmt"
func main() { func main() {
throttle := time.Tick(time.Millisecond * 200) throttle := time.Tick(time.Millisecond * 200)
for { for {
<- throttle <-throttle
go fmt.Println("rate-limited action") go fmt.Println("rate-limited action")
} }
} }

View File

@ -6,17 +6,17 @@ import "time"
import "fmt" import "fmt"
func main() { func main() {
timer1 := time.NewTimer(time.Second) timer1 := time.NewTimer(time.Second)
<- timer1.C <-timer1.C
fmt.Println("Timer 1 expired") fmt.Println("Timer 1 expired")
stop1 := timer1.Stop() stop1 := timer1.Stop()
fmt.Println("Timer 2 stopped:", stop1) fmt.Println("Timer 2 stopped:", stop1)
timer2 := time.NewTimer(time.Second) timer2 := time.NewTimer(time.Second)
go func() { go func() {
<- timer2.C <-timer2.C
fmt.Println("Timer 2 expired") fmt.Println("Timer 2 expired")
}() }()
stop2 := timer2.Stop() stop2 := timer2.Stop()
fmt.Println("Timer 2 stopped:", stop2) fmt.Println("Timer 2 stopped:", stop2)
} }

View File

@ -11,9 +11,9 @@ import "sort"
func main() { func main() {
// Sort methods are specific to the builtin type. // Sort methods are specific to the builtin type.
// Sorting is in-place (doesn't return a new slice). // Sorting is in-place (doesn't return a new slice).
strs := []string{"c", "a", "b"} strs := []string{"c", "a", "b"}
sort.Strings(strs) sort.Strings(strs)
fmt.Println(strs) fmt.Println(strs)
// Sorting methods are named after the type. // Sorting methods are named after the type.
ints := []int{7, 2, 4} ints := []int{7, 2, 4}

View File

@ -2,14 +2,18 @@
package main package main
import ("fmt" ; "sort") import (
"fmt"
"sort"
)
type Person struct { type Person struct {
Name string Name string
Age int Age int
} }
type ByName []Person type ByName []Person
func (this ByName) Len() int { func (this ByName) Len() int {
return len(this) return len(this)
} }
@ -21,8 +25,9 @@ func (this ByName) Swap(i, j int) {
} }
type ByAge []Person type ByAge []Person
func (this ByAge) Len() int { func (this ByAge) Len() int {
return len(this) return len(this)
} }
func (this ByAge) Less(i, j int) bool { func (this ByAge) Less(i, j int) bool {
return this[i].Age < this[j].Age return this[i].Age < this[j].Age
@ -33,15 +38,15 @@ func (this ByAge) Swap(i, j int) {
func main() { func main() {
kids := []Person{ kids := []Person{
{"Jack", 10}, {"Jack", 10},
{"Jill", 9}, {"Jill", 9},
{"Bob", 12}, {"Bob", 12},
} }
fmt.Println("Original:", kids) fmt.Println("Original:", kids)
sort.Sort(ByName(kids)) sort.Sort(ByName(kids))
fmt.Println("ByName: ", kids) fmt.Println("ByName: ", kids)
sort.Sort(ByAge(kids)) sort.Sort(ByAge(kids))
fmt.Println("ByAge: ", kids) fmt.Println("ByAge: ", kids)
} }

View File

@ -6,90 +6,90 @@ import "strings"
import "fmt" import "fmt"
func Index(elems []string, val string) int { func Index(elems []string, val string) int {
for i, v := range elems { for i, v := range elems {
if v == val { if v == val {
return i return i
} }
} }
return -1 return -1
} }
func Include(elems []string, val string) bool { 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 { func Any(elems []string, f func(string) bool) bool {
for _, v := range elems { for _, v := range elems {
if f(v) { if f(v) {
return true return true
} }
} }
return false return false
} }
func All(elems []string, f func(string)bool) bool { func All(elems []string, f func(string) bool) bool {
for _, v := range elems { for _, v := range elems {
if !f(v) { if !f(v) {
return false return false
} }
} }
return true return true
} }
func Filter(elems []string, f func(string)bool) []string { func Filter(elems []string, f func(string) bool) []string {
filtered := []string{} filtered := []string{}
for _, v := range elems { for _, v := range elems {
if f(v) { if f(v) {
filtered = append(filtered, v) filtered = append(filtered, v)
} }
} }
return filtered return filtered
} }
func Map(elems []string, f func(string)string) []string { func Map(elems []string, f func(string) string) []string {
mapped := make([]string, len(elems)) mapped := make([]string, len(elems))
for i, v := range elems { for i, v := range elems {
mapped[i] = f(v) mapped[i] = f(v)
} }
return mapped return mapped
} }
func main() { 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, "pear"))
fmt.Println(Index(elems, "grape")) fmt.Println(Index(elems, "grape"))
fmt.Println() fmt.Println()
fmt.Println(Include(elems, "pear")) fmt.Println(Include(elems, "pear"))
fmt.Println(Include(elems, "grape")) fmt.Println(Include(elems, "grape"))
fmt.Println() fmt.Println()
fmt.Println(Any(elems, func(v string) bool { fmt.Println(Any(elems, func(v string) bool {
return strings.HasPrefix(v, "p") return strings.HasPrefix(v, "p")
})) }))
fmt.Println(Any(elems, func(v string) bool { fmt.Println(Any(elems, func(v string) bool {
return strings.HasPrefix(v, "g") return strings.HasPrefix(v, "g")
})) }))
fmt.Println() fmt.Println()
fmt.Println(All(elems, func(v string) bool { fmt.Println(All(elems, func(v string) bool {
return strings.Contains(v, "a") return strings.Contains(v, "a")
})) }))
fmt.Println(All(elems, func(v string) bool { fmt.Println(All(elems, func(v string) bool {
return strings.Contains(v, "p") return strings.Contains(v, "p")
})) }))
fmt.Println() fmt.Println()
fmt.Println(Filter(elems, func(v string) bool { fmt.Println(Filter(elems, func(v string) bool {
return strings.Contains(v, "p") return strings.Contains(v, "p")
})) }))
fmt.Println() fmt.Println()
fmt.Println(Map(elems, func(s string) string { fmt.Println(Map(elems, func(s string) string {
return strings.ToUpper(s) return strings.ToUpper(s)
})) }))
fmt.Println() fmt.Println()
} }
// todo: generics // todo: generics

View File

@ -6,7 +6,7 @@ import "strings"
import "fm" import "fm"
func p(o interface{}) { func p(o interface{}) {
fmt.Println(o) fmt.Println(o)
} }
func main() { func main() {
@ -15,8 +15,8 @@ func main() {
p(strings.Count("test", "t")) p(strings.Count("test", "t"))
p(strings.HasPrefix("test", "te")) p(strings.HasPrefix("test", "te"))
p(strings.HasSuffix("test", "st")) p(strings.HasSuffix("test", "st"))
p(strings.Index("test", "e")) p(strings.Index("test", "e"))
p(strings.Join([]string{"a","b"}, "-")) p(strings.Join([]string{"a", "b"}, "-"))
p(strings.Repeat("a", 5)) p(strings.Repeat("a", 5))
p(strings.Replace("foo", "o", "0", -1)) p(strings.Replace("foo", "o", "0", -1))
p(strings.Replace("foo", "o", "0", 1)) p(strings.Replace("foo", "o", "0", 1))

View File

@ -6,14 +6,14 @@ import "regexp"
import "fmt" import "fmt"
func main() { func main() {
m1, _ := regexp.MatchString("p[a-z]+ch", "apple") m1, _ := regexp.MatchString("p[a-z]+ch", "apple")
m2, _ := regexp.MatchString("p[a-z]+ch", "peach") m2, _ := regexp.MatchString("p[a-z]+ch", "peach")
fmt.Println(m1) fmt.Println(m1)
fmt.Println(m2) fmt.Println(m2)
r1, _ := regexp.Compile("p[a-z]+ch") r1, _ := regexp.Compile("p[a-z]+ch")
fmt.Println(r1.MatchString("apple")) fmt.Println(r1.MatchString("apple"))
fmt.Println(r1.MatchString("peach")) fmt.Println(r1.MatchString("peach"))
} }
// todo: more // todo: more

View File

@ -5,8 +5,8 @@ package main
import "fmt" import "fmt"
func main() { func main() {
arr := []byte("some bytes") arr := []byte("some bytes")
str := string([]byte{'a', ' ', 's', 't', 'r', 'i', 'n', 'g'}) str := string([]byte{'a', ' ', 's', 't', 'r', 'i', 'n', 'g'})
fmt.Println(arr) fmt.Println(arr)
fmt.Println(str) fmt.Println(str)
} }

View File

@ -6,32 +6,34 @@ import "encoding/json"
import "fmt" import "fmt"
func main() { func main() {
// data to bytes/string // data to bytes/string
bol, _ := json.Marshal(true) bol, _ := json.Marshal(true)
fmt.Println(string(bol)) fmt.Println(string(bol))
num, _ := json.Marshal(1) num, _ := json.Marshal(1)
fmt.Println(string(num)) fmt.Println(string(num))
str, _ := json.Marshal("gopher") str, _ := json.Marshal("gopher")
fmt.Println(string(str)) fmt.Println(string(str))
arr, _ := json.Marshal([]string{"apple", "peach", "pear"}) arr, _ := json.Marshal([]string{"apple", "peach", "pear"})
fmt.Println(string(arr)) fmt.Println(string(arr))
hsh, _ := json.Marshal(map[string]int{"apple": 5, "lettuce": 7}) hsh, _ := json.Marshal(map[string]int{"apple": 5, "lettuce": 7})
fmt.Println(string(hsh)) fmt.Println(string(hsh))
// string to data // string to data
byt := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`) byt := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`)
var dat map[string]interface{} var dat map[string]interface{}
err := json.Unmarshal(byt, &dat) err := json.Unmarshal(byt, &dat)
if err != nil { panic(err) } if err != nil {
fmt.Println(dat) panic(err)
}
fmt.Println(dat)
name := dat["Name"].(string) name := dat["Name"].(string)
fmt.Println(name) fmt.Println(name)
parents := dat["Parents"].([]interface{}) parents := dat["Parents"].([]interface{})
fmt.Println(parents) fmt.Println(parents)
} }

View File

@ -7,13 +7,13 @@ import "time"
func main() { func main() {
// Use `time.Now` with `Unix` or `UnixNane` to get // Use `time.Now` with `Unix` or `UnixNane` to get
// elapsed time since the Unix epoch. // elapsed time since the Unix epoch.
now := time.Now() now := time.Now()
secs := now.Unix() secs := now.Unix()
nanos := now.UnixNano() nanos := now.UnixNano()
// There is no `UnixMillis`. // There is no `UnixMillis`.
millis := nanos / 1000000 millis := nanos / 1000000
println("Secs: ", secs) println("Secs: ", secs)
println("Millis:", millis) println("Millis:", millis)
println("Nanos: ", nanos) println("Nanos: ", nanos)
} }

View File

@ -6,7 +6,7 @@ import "time"
import "fmt" import "fmt"
func main() { func main() {
start := time.Now() start := time.Now()
time.Sleep(3 * time.Second) time.Sleep(3 * time.Second)
fmt.Println(time.Since(start)) fmt.Println(time.Since(start))
} }

View File

@ -10,30 +10,30 @@ import "fmt"
func main() { func main() {
// For example, `rand.Intn` returns a random `int` n, // For example, `rand.Intn` returns a random `int` n,
// `0 <= n < 100`. // `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() fmt.Println()
// `rand.Float64` returns a `float64` `f`, // `rand.Float64` returns a `float64` `f`,
// `0.0 <= f < 1.0`. // `0.0 <= f < 1.0`.
fmt.Println(rand.Float64()) fmt.Println(rand.Float64())
// To make the psuedo-random generator deterministic, // To make the psuedo-random generator deterministic,
// give it a well-known seed. // give it a well-known seed.
s1 := rand.NewSource(42) s1 := rand.NewSource(42)
r1 := rand.New(s1) r1 := rand.New(s1)
// Call the resulting `rand.Source` just like the // Call the resulting `rand.Source` just like the
// functions on the `rand` package. // functions on the `rand` package.
fmt.Print(r1.Intn(100), ",") fmt.Print(r1.Intn(100), ",")
fmt.Print(r1.Intn(100)) fmt.Print(r1.Intn(100))
fmt.Println() fmt.Println()
// If you seed a source with the same number, it // If you seed a source with the same number, it
// produces the same sequence of random numbers. // produces the same sequence of random numbers.
s2 := rand.NewSource(42) s2 := rand.NewSource(42)
r2 := rand.New(s2) r2 := rand.New(s2)
fmt.Print(r2.Intn(100), ",") fmt.Print(r2.Intn(100), ",")
fmt.Print(r2.Intn(100)) fmt.Print(r2.Intn(100))
fmt.Println() fmt.Println()
} }

View File

@ -13,5 +13,4 @@ func main() {
fmt.Print(string(contents)) fmt.Print(string(contents))
} }
// todo: streaming reads // todo: streaming reads

View File

@ -5,7 +5,7 @@ package main
import "os" import "os"
func main() { func main() {
file, err := os.Create("xx-file-write.txt") file, err := os.Create("xx-file-write.txt")
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@ -10,17 +10,16 @@ import "fmt"
func main() { func main() {
// `os.Args` includes the program name as the first // `os.Args` includes the program name as the first
// value. // value.
argsWithProg := os.Args argsWithProg := os.Args
argsWithoutProg := os.Args[1:] argsWithoutProg := os.Args[1:]
// `Args` are a slice, you can get individual args // `Args` are a slice, you can get individual args
// with normal indexing. // with normal indexing.
arg := os.Args[3] arg := os.Args[3]
fmt.Println(argsWithProg)
fmt.Println(argsWithProg) fmt.Println(argsWithoutProg)
fmt.Println(argsWithoutProg) fmt.Println(arg)
fmt.Println(arg)
} }
// todo: discuss building before here // todo: discuss building before here

View File

@ -8,11 +8,11 @@ import "fmt"
func main() { func main() {
maxp := flag.Int("repeat", 3, "time to repeat args") maxp := flag.Int("repeat", 3, "time to repeat args")
flag.Parse() flag.Parse()
for i := 0; i < *maxp; i++ { for i := 0; i < *maxp; i++ {
for _, arg := range flag.Args() { for _, arg := range flag.Args() {
fmt.Println(arg) fmt.Println(arg)
} }
} }
} }
// todo: multiple flags // todo: multiple flags

View File

@ -6,13 +6,13 @@ import "os/exec"
import "fmt" import "fmt"
func main() { func main() {
cmd := exec.Command("ls", "-a", "-l") cmd := exec.Command("ls", "-a", "-l")
out, err := cmd.Output() out, err := cmd.Output()
if err != nil { if err != nil {
panic(err) panic(err)
} }
fmt.Println("Files:") fmt.Println("Files:")
fmt.Print(string(out)) fmt.Print(string(out))
} }
// todo: full command lines with bash // todo: full command lines with bash

View File

@ -7,14 +7,14 @@ import "os"
import "os/exec" import "os/exec"
func main() { func main() {
binary, lookErr := exec.LookPath("ls") binary, lookErr := exec.LookPath("ls")
if lookErr != nil { if lookErr != nil {
panic(lookErr) panic(lookErr)
} }
execErr := syscall.Exec(binary, []string{"-a", "-l", "-h"}, os.Environ()) execErr := syscall.Exec(binary, []string{"-a", "-l", "-h"}, os.Environ())
if execErr != nil { if execErr != nil {
panic(execErr) panic(execErr)
} }
} }
// todo: note lack of fork // todo: note lack of fork

View File

@ -2,21 +2,26 @@
package main package main
import ("fmt"; "os"; "os/signal"; "syscall") import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() { func main() {
c := make(chan os.Signal, 1) c := make(chan os.Signal, 1)
d := make(chan bool, 1) d := make(chan bool, 1)
signal.Notify(c, syscall.SIGINT) signal.Notify(c, syscall.SIGINT)
go func(){ go func() {
sig := <- c sig := <-c
fmt.Println() fmt.Println()
fmt.Println(sig) fmt.Println(sig)
d <- true d <- true
}() }()
fmt.Println("Awaiting signal") fmt.Println("Awaiting signal")
<- d <-d
} }
// todo: sending signals? // todo: sending signals?

View File

@ -4,13 +4,13 @@ package main
// Use `os.Exit` to immediatly exit with a given // Use `os.Exit` to immediatly exit with a given
// status. // status.
import "os" import "os"
func main() { func main() {
// This `println` will never be reached because the // This `println` will never be reached because the
// exit is immediate. // exit is immediate.
defer println("!") defer println("!")
os.Exit(3) os.Exit(3)
} }
// todo: discuss building before getting here // todo: discuss building before getting here

View File

@ -7,11 +7,11 @@ import "io/ioutil"
import "fmt" import "fmt"
func main() { func main() {
resp, err := http.Get("http://127.0.0.1:5000/") resp, err := http.Get("http://127.0.0.1:5000/")
if err != nil { if err != nil {
panic(err) panic(err)
} }
defer resp.Body.Close() defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
fmt.Print(string(body)) fmt.Print(string(body))
} }

View File

@ -8,13 +8,15 @@ import "io/ioutil"
import "fmt" import "fmt"
func main() { func main() {
tr := &http.Transport{ tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
} }
client := &http.Client{Transport: tr} client := &http.Client{Transport: tr}
resp, err := client.Get("https://127.0.0.1:5000/") resp, err := client.Get("https://127.0.0.1:5000/")
if err != nil { panic(err) } if err != nil {
defer resp.Body.Close() panic(err)
body, _ := ioutil.ReadAll(resp.Body) }
fmt.Print(string(body)) defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Print(string(body))
} }

View File

@ -7,60 +7,70 @@ import "time"
import "fmt" import "fmt"
func main() { func main() {
// initialize // initialize
conf := redis.DefaultConfig() conf := redis.DefaultConfig()
client := redis.NewClient(conf) client := redis.NewClient(conf)
fmt.Println(conf) fmt.Println(conf)
fmt.Println(client) fmt.Println(client)
// set & get // set & get
setRep := client.Set("foo", "bar") setRep := client.Set("foo", "bar")
if setRep.Err != nil { panic(setRep.Err) } if setRep.Err != nil {
fmt.Println(setRep) panic(setRep.Err)
getRep := client.Get("foo") }
if getRep.Err != nil { panic(getRep.Err) } fmt.Println(setRep)
getStr, _ := getRep.Str() getRep := client.Get("foo")
fmt.Println(getRep) if getRep.Err != nil {
fmt.Println(getStr) panic(getRep.Err)
}
getStr, _ := getRep.Str()
fmt.Println(getRep)
fmt.Println(getStr)
// varadic calls // varadic calls
client.Set("foo1", "bar1") client.Set("foo1", "bar1")
client.Set("foo2", "bar2") client.Set("foo2", "bar2")
client.Set("foo3", "bar3") client.Set("foo3", "bar3")
mgetRep := client.Mget("foo1", "foo2", "foo3") mgetRep := client.Mget("foo1", "foo2", "foo3")
fmt.Println(mgetRep) fmt.Println(mgetRep)
// multi calls // multi calls
mcallRep := client.MultiCall(func(mc *redis.MultiCall) { mcallRep := client.MultiCall(func(mc *redis.MultiCall) {
mc.Set("k1", "v1") mc.Set("k1", "v1")
mc.Get("k1") mc.Get("k1")
}) })
if mcallRep.Err != nil { panic(mcallRep.Err) } if mcallRep.Err != nil {
mcallVal, _ := mcallRep.Elems[1].Str() panic(mcallRep.Err)
fmt.Println(mcallVal) }
mcallVal, _ := mcallRep.Elems[1].Str()
fmt.Println(mcallVal)
// transactional calls // transactional calls
tranRep := client.Transaction(func(mc *redis.MultiCall) { tranRep := client.Transaction(func(mc *redis.MultiCall) {
mc.Set("k2", "v2") mc.Set("k2", "v2")
mc.Get("k2") mc.Get("k2")
}) })
if tranRep.Err != nil { panic(tranRep.Err) } if tranRep.Err != nil {
tranStr, _ := tranRep.Elems[1].Str() panic(tranRep.Err)
fmt.Println(tranStr) }
tranStr, _ := tranRep.Elems[1].Str()
fmt.Println(tranStr)
// pubsub // pubsub
msgHdlr := func(msg *redis.Message) { msgHdlr := func(msg *redis.Message) {
fmt.Println(msg) fmt.Println(msg)
} }
sub, subErr := client.Subscription(msgHdlr) sub, subErr := client.Subscription(msgHdlr)
if subErr != nil { panic(subErr) } if subErr != nil {
defer sub.Close() panic(subErr)
sub.Subscribe("chan1", "chan2") }
sub.Psubscribe("chan*") defer sub.Close()
client.Publish("chan1", "foo") sub.Subscribe("chan1", "chan2")
sub.Unsubscribe("chan1") sub.Psubscribe("chan*")
client.Publish("chan2", "bar") client.Publish("chan1", "foo")
time.Sleep(time.Second) sub.Unsubscribe("chan1")
client.Publish("chan2", "bar")
time.Sleep(time.Second)
} }
// todo: connection pooling & concurrency? // todo: connection pooling & concurrency?

View File

@ -8,46 +8,60 @@ import "time"
import "fmt" import "fmt"
func main() { func main() {
db, openErr := sql.Open("postgres", "dbname=gobyexample sslmode=disable") db, openErr := sql.Open("postgres", "dbname=gobyexample sslmode=disable")
if openErr != nil { panic(openErr) } if openErr != nil {
defer db.Close() panic(openErr)
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() defer db.Close()
if rowsErr != nil { panic(rowsErr) } fmt.Println(db)
dropRep, dropErr := db.Exec("DROP TABLE items") createRep, createErr := db.Exec("CREATE TABLE items (a int, b float, c boolean, d text, e timestamp with time zone)")
if dropErr != nil { panic(dropErr) } if createErr != nil {
fmt.Println(dropRep) 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 // todo: connection pooling & concurrency

View File

@ -5,21 +5,23 @@ package main
import "net/smtp" import "net/smtp"
func main() { func main() {
auth := smtp.PlainAuth( auth := smtp.PlainAuth(
"", "",
"mark@heroku.com", "mark@heroku.com",
"xxx", "xxx",
"smtp.gmail.com", "smtp.gmail.com",
) )
err := smtp.SendMail( err := smtp.SendMail(
"smtp.gmail.com:25", "smtp.gmail.com:25",
auth, auth,
"mark+sent@heroku.com", "mark+sent@heroku.com",
[]string{"mark@heroku.com"}, []string{"mark@heroku.com"},
[]byte("nThe body."), []byte("nThe body."),
) )
if err != nil { panic(err) } if err != nil {
panic(err)
}
} }
// todo: missing subject, cc, bcc // todo: missing subject, cc, bcc

View File

@ -6,7 +6,7 @@ import "net/http"
func hello(res http.ResponseWriter, req *http.Request) { func hello(res http.ResponseWriter, req *http.Request) {
res.Header().Set("Content-Type", "text/plain") res.Header().Set("Content-Type", "text/plain")
res.Write([]byte("Hello web\n")) res.Write([]byte("Hello web\n"))
} }
func main() { func main() {

View File

@ -6,13 +6,13 @@ import "net/http"
import "fmt" import "fmt"
func hello(res http.ResponseWriter, req *http.Request) { func hello(res http.ResponseWriter, req *http.Request) {
res.Header().Set("Content-Type", "text/plain") res.Header().Set("Content-Type", "text/plain")
if req.URL.Path == "/protected" { if req.URL.Path == "/protected" {
res.WriteHeader(401) res.WriteHeader(401)
fmt.Fprintln(res, "Not allowed") fmt.Fprintln(res, "Not allowed")
} else { } else {
fmt.Fprintln(res, "Hello") fmt.Fprintln(res, "Hello")
} }
} }
func main() { func main() {

View File

@ -7,13 +7,13 @@ import "net/http"
import "fmt" import "fmt"
func hello(w http.ResponseWriter, req *http.Request) { 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() { func main() {
p := pat.New() p := pat.New()
p.Get("/hello/:name", http.HandlerFunc(hello)) p.Get("/hello/:name", http.HandlerFunc(hello))
http.ListenAndServe(":5000", p) http.ListenAndServe(":5000", p)
} }
// todo: consider gorilla-web // todo: consider gorilla-web

View File

@ -7,32 +7,32 @@ import "time"
import "fmt" import "fmt"
func runLogging(logs chan string) { func runLogging(logs chan string) {
for log := range logs { for log := range logs {
fmt.Println(log) fmt.Println(log)
} }
} }
func wrapLogging(f http.HandlerFunc) http.HandlerFunc { func wrapLogging(f http.HandlerFunc) http.HandlerFunc {
logs := make(chan string, 10000) logs := make(chan string, 10000)
go runLogging(logs) go runLogging(logs)
return func(res http.ResponseWriter, req *http.Request) { return func(res http.ResponseWriter, req *http.Request) {
start := time.Now() start := time.Now()
f(res, req) f(res, req)
method := req.Method method := req.Method
path := req.URL.Path path := req.URL.Path
elapsed := float64(time.Since(start)) / 1000000.0 elapsed := float64(time.Since(start)) / 1000000.0
logs <- fmt.Sprintf("method=%s path=%s elapsed=%f", method, path, elapsed) logs <- fmt.Sprintf("method=%s path=%s elapsed=%f", method, path, elapsed)
} }
} }
func hello(res http.ResponseWriter, req *http.Request) { func hello(res http.ResponseWriter, req *http.Request) {
res.Header().Set("Content-Type", "text/plain") res.Header().Set("Content-Type", "text/plain")
time.Sleep(time.Millisecond * 50) time.Sleep(time.Millisecond * 50)
fmt.Fprintln(res, "Hello logged world") fmt.Fprintln(res, "Hello logged world")
} }
func main() { func main() {
handler := wrapLogging(hello) handler := wrapLogging(hello)
http.HandleFunc("/", handler) http.HandleFunc("/", handler)
http.ListenAndServe(":5000", nil) http.ListenAndServe(":5000", nil)
} }

View File

@ -5,8 +5,8 @@ package main
import "net/http" import "net/http"
func main() { func main() {
handler := http.FileServer(http.Dir("./")) handler := http.FileServer(http.Dir("./"))
http.ListenAndServe(":5000", handler) http.ListenAndServe(":5000", handler)
} }
// todo: index pages // todo: index pages

View File

@ -3,44 +3,44 @@
package main package main
import ( import (
"net/http" "encoding/base64"
"encoding/base64" "fmt"
"strings" "net/http"
"fmt" "strings"
) )
type Authenticator func(string, string) bool type Authenticator func(string, string) bool
func testAuth(r *http.Request, auth Authenticator) bool { func testAuth(r *http.Request, auth Authenticator) bool {
s := strings.SplitN(r.Header.Get("Authorization"), " ", 2) s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
if len(s) != 2 || s[0] != "Basic" { if len(s) != 2 || s[0] != "Basic" {
return false return false
} }
b, err := base64.StdEncoding.DecodeString(s[1]) b, err := base64.StdEncoding.DecodeString(s[1])
if err != nil { if err != nil {
return false return false
} }
pair := strings.SplitN(string(b), ":", 2) pair := strings.SplitN(string(b), ":", 2)
if len(pair) != 2 { if len(pair) != 2 {
return false return false
} }
return auth(pair[0], pair[1]) return auth(pair[0], pair[1])
} }
func requireAuth(w http.ResponseWriter, r *http.Request) { func requireAuth(w http.ResponseWriter, r *http.Request) {
w.Header().Set("WWW-Authenticate", `Basic realm="private"`) w.Header().Set("WWW-Authenticate", `Basic realm="private"`)
w.WriteHeader(401) w.WriteHeader(401)
w.Write([]byte("401 Unauthorized\n")) w.Write([]byte("401 Unauthorized\n"))
} }
func wrapAuth(h http.HandlerFunc, a Authenticator) http.HandlerFunc { func wrapAuth(h http.HandlerFunc, a Authenticator) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
if testAuth(r, a) { if testAuth(r, a) {
h(w, r) h(w, r)
} else { } else {
requireAuth(w, r) requireAuth(w, r)
} }
} }
} }
func hello(w http.ResponseWriter, r *http.Request) { func hello(w http.ResponseWriter, r *http.Request) {
@ -48,10 +48,10 @@ func hello(w http.ResponseWriter, r *http.Request) {
} }
func main() { func main() {
checkPassword := func(_, password string) bool { checkPassword := func(_, password string) bool {
return password == "supersecret" return password == "supersecret"
} }
handler1 := http.HanderFunc(hello) handler1 := http.HanderFunc(hello)
handler2 := wrapAuth(handler1, checkPassword) handler2 := wrapAuth(handler1, checkPassword)
http.ListenAndServe(":5000", handler2) http.ListenAndServe(":5000", handler2)
} }

View File

@ -8,26 +8,26 @@ import "fmt"
func hello(res http.ResponseWriter, req *http.Request) { func hello(res http.ResponseWriter, req *http.Request) {
res.Header().Set("Content-Type", "text/plain") 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 { func wrapCanonicalHost(f http.HandlerFunc, canonicalHost string) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) { return func(res http.ResponseWriter, req *http.Request) {
hostPort := strings.Split(req.Host, ":") hostPort := strings.Split(req.Host, ":")
host := hostPort[0] host := hostPort[0]
if host != canonicalHost { if host != canonicalHost {
fmt.Println("redirecting from", host, "to", canonicalHost) fmt.Println("redirecting from", host, "to", canonicalHost)
hostPort[0] = canonicalHost hostPort[0] = canonicalHost
url := "http://" + strings.Join(hostPort, ":") + req.URL.String() url := "http://" + strings.Join(hostPort, ":") + req.URL.String()
http.Redirect(res, req, url, 301) http.Redirect(res, req, url, 301)
return return
} }
f(res, req) f(res, req)
} }
} }
func main() { func main() {
handler := wrapCanonicalHost(hello, "localhost") handler := wrapCanonicalHost(hello, "localhost")
http.HandleFunc("/", handler) http.HandleFunc("/", handler)
http.ListenAndServe(":5000", nil) http.ListenAndServe(":5000", nil)
} }

View File

@ -7,19 +7,19 @@ import "fmt"
func hello(res http.ResponseWriter, req *http.Request) { func hello(res http.ResponseWriter, req *http.Request) {
res.Header().Set("Content-Type", "text/plain") 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 { func wrapMiddleware(f http.HandlerFunc) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) { return func(res http.ResponseWriter, req *http.Request) {
fmt.Println("before") fmt.Println("before")
f(res, req) f(res, req)
fmt.Println("after") fmt.Println("after")
} }
} }
func main() { func main() {
handler := wrapMiddleware(hello) handler := wrapMiddleware(hello)
http.HandleFunc("/", handler) http.HandleFunc("/", handler)
http.ListenAndServe(":5000", nil) http.ListenAndServe(":5000", nil)
} }

View File

@ -3,88 +3,92 @@
package main package main
import ( import (
"fmt"
"net" "net"
"net/http" "net/http"
"time"
"os" "os"
"os/signal" "os/signal"
"syscall"
"fmt"
"sync/atomic" "sync/atomic"
"syscall"
"time"
) )
func slow(res http.ResponseWriter, req *http.Request) { func slow(res http.ResponseWriter, req *http.Request) {
fmt.Println("respond at=start") fmt.Println("respond at=start")
time.Sleep(time.Second * 5) time.Sleep(time.Second * 5)
res.Header().Set("Content-Type", "text/plain") res.Header().Set("Content-Type", "text/plain")
fmt.Fprintln(res, "Finally.") fmt.Fprintln(res, "Finally.")
fmt.Println("respond at=finish") fmt.Println("respond at=finish")
} }
var connCount int64 = 0 var connCount int64 = 0
type watchedConn struct { type watchedConn struct {
net.Conn net.Conn
} }
func (w *watchedConn) Close() error { func (w *watchedConn) Close() error {
atomic.AddInt64(&connCount, -1) atomic.AddInt64(&connCount, -1)
return w.Conn.Close() return w.Conn.Close()
} }
type watchedListener struct { type watchedListener struct {
net.Listener net.Listener
} }
func (l *watchedListener) Accept() (net.Conn, error) { func (l *watchedListener) Accept() (net.Conn, error) {
conn, err := l.Listener.Accept() conn, err := l.Listener.Accept()
if err != nil { if err != nil {
return nil, err return nil, err
} }
atomic.AddInt64(&connCount, 1) atomic.AddInt64(&connCount, 1)
return &watchedConn{Conn: conn}, nil return &watchedConn{Conn: conn}, nil
} }
func main() { func main() {
stop := make(chan bool, 1) stop := make(chan bool, 1)
sig := make(chan os.Signal, 1) sig := make(chan os.Signal, 1)
server := &http.Server{Handler: http.HandlerFunc(slow)} server := &http.Server{Handler: http.HandlerFunc(slow)}
fmt.Println("listen at=start") fmt.Println("listen at=start")
listener, listenErr := net.Listen("tcp", ":5000") listener, listenErr := net.Listen("tcp", ":5000")
if listenErr != nil { panic(listenErr) } if listenErr != nil {
wListener := &watchedListener{Listener: listener} panic(listenErr)
fmt.Println("listen at=finish") }
wListener := &watchedListener{Listener: listener}
fmt.Println("listen at=finish")
go func() { go func() {
<- stop <-stop
fmt.Println("close at=start") fmt.Println("close at=start")
closeErr := wListener.Close() closeErr := wListener.Close()
if closeErr != nil { panic(closeErr) } if closeErr != nil {
fmt.Println("close at=finish") panic(closeErr)
}() }
fmt.Println("close at=finish")
}()
go func() { go func() {
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM) signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
fmt.Println("trap at=start") fmt.Println("trap at=start")
<- sig <-sig
stop <- true stop <- true
fmt.Println("trap at=finish") fmt.Println("trap at=finish")
}() }()
fmt.Println("serve at=start") fmt.Println("serve at=start")
server.Serve(wListener) server.Serve(wListener)
fmt.Println("serve at=finish") fmt.Println("serve at=finish")
for { for {
connCountCurrent := atomic.LoadInt64(&connCount) connCountCurrent := atomic.LoadInt64(&connCount)
if connCountCurrent > 0 { if connCountCurrent > 0 {
fmt.Println("wait at=pending remaining=", connCountCurrent) fmt.Println("wait at=pending remaining=", connCountCurrent)
time.Sleep(time.Second) time.Sleep(time.Second)
} else { } else {
fmt.Println("wait at=finish remaining=", connCountCurrent) fmt.Println("wait at=finish remaining=", connCountCurrent)
return return
} }
} }
} }
// todo: clean up logging // todo: clean up logging

View File

@ -5,12 +5,14 @@ package main
import "net/http" import "net/http"
func handler(res http.ResponseWriter, req *http.Request) { func handler(res http.ResponseWriter, req *http.Request) {
res.Header().Set("Content-Type", "text/plain") res.Header().Set("Content-Type", "text/plain")
res.Write([]byte("Hello from HTTPS\n")) res.Write([]byte("Hello from HTTPS\n"))
} }
func main() { func main() {
http.HandleFunc("/", handler) http.HandleFunc("/", handler)
err := http.ListenAndServeTLS(":5000", "/tmp/server.crt", "/tmp/server.key", nil) err := http.ListenAndServeTLS(":5000", "/tmp/server.crt", "/tmp/server.key", nil)
if err != nil { panic(err) } if err != nil {
panic(err)
}
} }

View File

@ -6,14 +6,14 @@ package main
import ( import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"strings"
"regexp"
"os" "os"
"regexp"
"sort" "sort"
"strings"
) )
func minInt(a, b int) int { func minInt(a, b int) int {
if (a < b) { if a < b {
return a return a
} }
return b return b
@ -24,7 +24,9 @@ func main() {
sourceNames := make([]string, 0) sourceNames := make([]string, 0)
sourceMap := make(map[string]string) sourceMap := make(map[string]string)
fileInfos, dirErr := ioutil.ReadDir("./") fileInfos, dirErr := ioutil.ReadDir("./")
if dirErr != nil { panic(dirErr) } if dirErr != nil {
panic(dirErr)
}
baseTrimmer, _ := regexp.Compile("[0-9x]+-") baseTrimmer, _ := regexp.Compile("[0-9x]+-")
for _, fi := range fileInfos { for _, fi := range fileInfos {
baseName := baseTrimmer.ReplaceAllString(fi.Name(), "") baseName := baseTrimmer.ReplaceAllString(fi.Name(), "")
@ -36,11 +38,13 @@ func main() {
// read names from index // read names from index
indexBytes, idxErr := ioutil.ReadFile("tool/index.txt") indexBytes, idxErr := ioutil.ReadFile("tool/index.txt")
if idxErr != nil { panic (idxErr) } if idxErr != nil {
panic(idxErr)
}
indexNamesAll := strings.Split(string(indexBytes), "\n") indexNamesAll := strings.Split(string(indexBytes), "\n")
indexNames := make([]string, 0) indexNames := make([]string, 0)
for _, indexName := range indexNamesAll { for _, indexName := range indexNamesAll {
if indexName != "" && !strings.Contains(indexName, "#") && !strings.Contains(indexName, "~") { if indexName != "" && !strings.Contains(indexName, "#") && !strings.Contains(indexName, "~") {
indexNames = append(indexNames, indexName) indexNames = append(indexNames, indexName)
} }
} }