diff --git a/channel-close.go b/channel-close.go new file mode 100644 index 0000000..86c0448 --- /dev/null +++ b/channel-close.go @@ -0,0 +1,30 @@ +package main + +import "fmt" + +func main() { + jobs := make(chan int, 5) + done := make(chan bool) + + go func() { + for { + j, more := <-jobs + if more { + fmt.Println("received job", j) + } else { + fmt.Println("received all jobs") + done <- true + return + } + } + }() + + for j := 1; j <= 3; j++ { + jobs <- j + fmt.Println("sent job", j) + } + close(jobs) + fmt.Println("sent all jobs") + + <-done +} diff --git a/channel-directions.go b/channel-directions.go new file mode 100644 index 0000000..7006fe2 --- /dev/null +++ b/channel-directions.go @@ -0,0 +1,20 @@ +package main + +import "fmt" + +func ping(pings chan<- string, msg string) { + pings <- msg +} + +func pong(pings <-chan string, pongs chan<- string) { + msg := <-pings + pongs <- msg +} + +func main() { + pings := make(chan string, 1) + pongs := make(chan string, 1) + ping(pings, "passed message") + pong(pings, pongs) + fmt.Println(<-pongs) +} diff --git a/channel-sync.go b/channel-sync.go new file mode 100644 index 0000000..7914336 --- /dev/null +++ b/channel-sync.go @@ -0,0 +1,34 @@ +package main + +import ( + "fmt" + "time" +) + +func signal() chan bool { + return make(chan bool, 1) +} + +func worker(done chan bool, wkrnum int) { + fmt.Println("BEGIN: ", wkrnum) + fmt.Println("Wait 5 seconds...", wkrnum) + time.Sleep(time.Duration(5 * time.Second)) + fmt.Printf("%d plus %d equals %d\n", wkrnum, 5, 5+wkrnum) + time.Sleep(time.Duration(5000)) + fmt.Println("END: ", wkrnum) + + done <- true +} + +func main() { + + done1 := signal() + go worker(done1, 1) + <-done1 + done2 := signal() + go worker(done2, 2) + <-done2 + done3 := signal() + go worker(done3, 3) + <-done3 +} diff --git a/channels.go b/channels.go new file mode 100644 index 0000000..c0a9ac6 --- /dev/null +++ b/channels.go @@ -0,0 +1,49 @@ +package main + +import ( + "fmt" + "strings" +) + +func simpleping() { + messages := make(chan string) + go func() { + messages <- "ping" + }() + msg := <-messages + fmt.Println(msg) + if msg == "ping" { + fmt.Println("pong") + } +} + +func snd(msgchan chan string, msgs []string) { + for i := 0; i < len(msgs); i++ { + msgchan <- msgs[i] + } +} + +func rcv(msgchan chan string) string { + var sentence []string + var msglen int = len(msgchan) + for v := range msgchan { + fmt.Println(len(sentence), sentence) + if len(sentence) == msglen-1 { // when we reach next to last in the array, do the last. + sentence = append(sentence, v) + break + } else { + sentence = append(sentence, v) + } + } + return strings.Join(sentence, " ") +} + +func main() { + simpleping() + + var words = []string{"buffered", "channel", "one", "two", "three", "four", "five", "six"} + msgchan := make(chan string, len(words)) + snd(msgchan, words) + fmt.Println(rcv(msgchan)) + +} diff --git a/check-versions b/check-versions new file mode 100755 index 0000000..e91823a Binary files /dev/null and b/check-versions differ diff --git a/check-versions.go b/check-versions.go new file mode 100644 index 0000000..1f30325 --- /dev/null +++ b/check-versions.go @@ -0,0 +1,40 @@ +package main + +import ( + "fmt" + "os" + "os/exec" + "runtime" + "strings" +) + +func validateos() { + if runtime.GOOS == "windows" { + fmt.Println("Can't Execute this on a windows machine") + os.Exit(1) + } +} + +func execute(cmdstr string) { + + validateos() + + var cmdargs = strings.Split(cmdstr, " ") // string arrayified + var cmd = cmdargs[0] // command + cmdargs = append(cmdargs[:0], cmdargs[1:]...) // argument array sans cmd + out, err := exec.Command(cmd, cmdargs...).CombinedOutput() + if err != nil { + fmt.Println(err) + } + output := string(out[:]) + fmt.Println(output) +} + +func main() { + execute("/usr/sbin/lsof -iTCP -sTCP:LISTEN") + execute("gcc --version") + execute("java -version") + execute("python3 --version") + execute("php --version") + +} diff --git a/handlers.go b/handlers.go new file mode 100644 index 0000000..52c75da --- /dev/null +++ b/handlers.go @@ -0,0 +1,57 @@ +package main + +import ( + "errors" + "fmt" +) + +func f1(arg int) (int, error) { + if arg == 42 { + + return -1, errors.New("can't work with 42") + + } + + return arg + 3, nil +} + +type argError struct { + arg int + prob string +} + +func (e *argError) Error() string { + return fmt.Sprintf("%d - %s", e.arg, e.prob) +} + +func f2(arg int) (int, error) { + if arg == 42 { + + return -1, &argError{arg, "can't work with it"} + } + return arg + 3, nil +} + +func main() { + + for _, i := range []int{7, 42} { + if r, e := f1(i); e != nil { + fmt.Println("f1 failed:", e) + } else { + fmt.Println("f1 worked:", r) + } + } + for _, i := range []int{7, 42} { + if r, e := f2(i); e != nil { + fmt.Println("f2 failed:", e) + } else { + fmt.Println("f2 worked:", r) + } + } + + _, e := f2(42) + if ae, ok := e.(*argError); ok { + fmt.Println(ae.arg) + fmt.Println(ae.prob) + } +} \ No newline at end of file diff --git a/interfaces.go b/interfaces.go new file mode 100644 index 0000000..7b25cbf --- /dev/null +++ b/interfaces.go @@ -0,0 +1,49 @@ +package main + +import ( + "fmt" + "math" +) + +// I have changed the names of the types and interface methods because they conflict with +// the go native library + +type geometry interface { + areaa() float64 + perimm() float64 +} + +type recta struct { + width, height float64 +} +type circle struct { + radius float64 +} + +func (r recta) areaa() float64 { + return r.width * r.height +} +func (r recta) perimm() float64 { + return 2*r.width + 2*r.height +} + +func (c circle) areaa() float64 { + return math.Pi * c.radius * c.radius +} +func (c circle) perimm() float64 { + return 2 * math.Pi * c.radius +} + +func measure(g geometry) { + fmt.Println(g) + fmt.Println(g.areaa()) + fmt.Println(g.perimm()) + +} + +func main() { + r := recta{width: 3, height: 4} + c := circle{radius: 5} + measure(r) + measure(c) +} diff --git a/non-blocks.go b/non-blocks.go new file mode 100644 index 0000000..7e28808 --- /dev/null +++ b/non-blocks.go @@ -0,0 +1,32 @@ +package main + +import "fmt" + +func main() { + messages := make(chan string) + signals := make(chan bool) + + select { + case msg := <-messages: + fmt.Println("received message", msg) + default: + fmt.Println("no message received") + } + + msg := "hi" + select { + case messages <- msg: + fmt.Println("sent message", msg) + default: + fmt.Println("no message sent") + } + + select { + case msg := <-messages: + fmt.Println("received message", msg) + case sig := <-signals: + fmt.Println("received signal", sig) + default: + fmt.Println("no activity") + } +} diff --git a/select-switch.go b/select-switch.go new file mode 100644 index 0000000..ba2aeb3 --- /dev/null +++ b/select-switch.go @@ -0,0 +1,30 @@ +package main + +import ( + "fmt" + "time" +) + +func main() { + + c1 := make(chan string) + c2 := make(chan string) + + go func() { + time.Sleep(1 * time.Second) + c1 <- "one" + }() + go func() { + time.Sleep(2 * time.Second) + c2 <- "two" + }() + + for i := 0; i < 2; i++ { + select { + case msg1 := <-c1: + fmt.Println("received", msg1) + case msg2 := <-c2: + fmt.Println("received", msg2) + } + } +} diff --git a/timeouts.go b/timeouts.go new file mode 100644 index 0000000..159cc19 --- /dev/null +++ b/timeouts.go @@ -0,0 +1,34 @@ +package main + +import ( + "fmt" + "time" +) + +func main() { + + c1 := make(chan string, 1) + go func() { + time.Sleep(5 * time.Second) + c1 <- "channel 1 response!" + }() + + select { + case res := <-c1: + fmt.Println(res) + case <-time.After(3 * time.Second): + fmt.Println("channel 1 timeout!") + } + + c2 := make(chan string, 1) + go func() { + time.Sleep(2 * time.Second) + c2 <- "channel 2 response!" + }() + select { + case res := <-c2: + fmt.Println(res) + case <-time.After(3 * time.Second): + fmt.Println("timeout 2") + } +}