├── 01.go ├── 09.go ├── 02.go ├── README.md ├── 03.go ├── 10.go ├── 11.go ├── 12.go ├── 14.go ├── 15.go ├── 05.go ├── 04.go ├── 07.go ├── 13.go ├── 06.go └── 08.go /01.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | fmt.Println("Hello, 15-440") 9 | } 10 | -------------------------------------------------------------------------------- /09.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type myMsg struct { 8 | seqNum int 9 | message string 10 | } 11 | 12 | func main() { 13 | fmt.Println("Go channels starting") 14 | } 15 | -------------------------------------------------------------------------------- /02.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | classname := "15-440" // Type inference 9 | 10 | fmt.Println("Hello,", classname) 11 | 12 | greeting := "你好" 13 | 14 | fmt.Println(greeting, classname) 15 | } 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | intro-to-go 2 | =========== 3 | 4 | This repository contains code snippets discussed in 15-440, lecture 4 (given on 1/23/2014). 5 | 6 | To clone this repository, execute the following command: 7 | 8 | ```sh 9 | git clone https://github.com/cmu440/intro-to-go 10 | ``` 11 | 12 | To run the file named `01.go`, simply execute: 13 | 14 | ```sh 15 | go run 01.go 16 | ``` 17 | -------------------------------------------------------------------------------- /03.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | classname := "15-440" // Type inference 9 | 10 | fmt.Println("Hello,", classname) 11 | 12 | fmt.Println("Hello half-class: ", classname[0:3]) 13 | 14 | fooname := classname[0:3] 15 | fmt.Println("Hello fooclass: ", fooname) 16 | 17 | // classname[0] = 'C' // Strings are immutable! 18 | // fooname[0] = 'C' // A slice refs the original 19 | 20 | // buf := []byte(classname) 21 | // buf[0] = byte('C') 22 | // fmt.Println(string(buf)) 23 | } 24 | -------------------------------------------------------------------------------- /10.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | type myMsg struct { 9 | seqNum int 10 | message string 11 | } 12 | 13 | func main() { 14 | fmt.Println("Go channels starting") 15 | 16 | ch := make(chan *myMsg) // unbuffered 17 | go chanSender(ch) 18 | 19 | for msg := range ch { 20 | fmt.Println("Message", msg.seqNum, ":", msg.message) 21 | } 22 | } 23 | 24 | func chanSender(out chan<- *myMsg) { 25 | seqNum := 0 26 | for i := 0; i < 5; i++ { 27 | time.Sleep(1*time.Second) 28 | out <- &myMsg{seqNum, "moo"} 29 | seqNum++ 30 | } 31 | close(out) 32 | } -------------------------------------------------------------------------------- /11.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | type myMsg struct { 9 | seqNum int 10 | message string 11 | } 12 | 13 | func main() { 14 | fmt.Println("Go channels starting") 15 | 16 | ch := make(chan *myMsg) // unbuffered 17 | go chanSender(ch, "cs1") 18 | go chanSender(ch, "cs2") 19 | 20 | for msg := range ch { 21 | fmt.Println("Message", msg.seqNum, ":", msg.message) 22 | } 23 | } 24 | 25 | func chanSender(out chan<- *myMsg, prefix string) { 26 | seqNum := 0 27 | for i := 0; i < 5; i++ { 28 | time.Sleep(1*time.Second) 29 | out <- &myMsg{seqNum, fmt.Sprintf("%s: %s", prefix, "moo")} 30 | seqNum++ 31 | } 32 | close(out) 33 | } -------------------------------------------------------------------------------- /12.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | type myMsg struct { 9 | seqNum int 10 | message string 11 | } 12 | 13 | func main() { 14 | fmt.Println("Go channels starting") 15 | 16 | ch1 := make(chan *myMsg) 17 | go chanSender(ch1, "cs1") 18 | 19 | ch2 := make(chan *myMsg) 20 | go chanSender(ch2, "cs2") 21 | 22 | for { 23 | select { 24 | case msg := <-ch1: 25 | fmt.Println("CH1: ", msg.seqNum, ":", msg.message) 26 | case msg := <-ch2: 27 | fmt.Println("CH2: ", msg.seqNum, ":", msg.message) 28 | } 29 | } 30 | } 31 | 32 | func chanSender(out chan<- *myMsg, prefix string) { 33 | seqNum := 0 34 | for i := 0; i < 5; i++ { 35 | time.Sleep(1*time.Second) 36 | out <- &myMsg{seqNum, fmt.Sprintf("%s: %s", prefix, "moo")} 37 | seqNum++ 38 | } 39 | close(out) 40 | } -------------------------------------------------------------------------------- /14.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type responseMsg struct { 8 | hash int 9 | } 10 | 11 | type requestMsg struct { 12 | nonce int 13 | responseChan chan *responseMsg 14 | } 15 | 16 | func main() { 17 | fmt.Println("Go channels starting") 18 | 19 | requestChan := make(chan *requestMsg) 20 | 21 | go chanWorker(requestChan) 22 | 23 | for i := 0; i < 5; i++ { 24 | request := &requestMsg{i, make(chan *responseMsg)} 25 | requestChan <- request 26 | response := <- request.responseChan 27 | fmt.Println("Got response: ", response.hash) 28 | } 29 | } 30 | 31 | func chanWorker(requestChan <-chan *requestMsg) { 32 | for req := range requestChan { 33 | respVal := req.nonce * 1234567; // Super-secure hash 34 | response := &responseMsg{respVal} 35 | req.responseChan <- response 36 | } 37 | } -------------------------------------------------------------------------------- /15.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | ) 8 | 9 | type ReaderCloser interface { 10 | Read(p []byte) (n int, err error) 11 | Close() error 12 | } 13 | 14 | func handleConn(conn ReaderCloser) { // conn net.Conn) { 15 | fmt.Println("Reading once from connection") 16 | 17 | var buf [1024]byte 18 | n, _ := conn.Read(buf[:]) 19 | fmt.Println("Client sent: ", string(buf[0:n])) 20 | conn.Close() 21 | } 22 | 23 | func main() { 24 | ln, err := net.Listen("tcp", ":15440") 25 | if err != nil { 26 | fmt.Println("Couldn't listen: ", err) 27 | os.Exit(-1) 28 | } 29 | for { 30 | fmt.Println("Waiting for inbound connection") 31 | conn, err := ln.Accept() 32 | if err != nil { 33 | fmt.Println("Couldn't accept: ", err) 34 | os.Exit(-1) 35 | } 36 | go handleConn(conn) 37 | } 38 | fmt.Println("All done") 39 | 40 | } 41 | -------------------------------------------------------------------------------- /05.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" // go fmt puts these in alphbetical order. 7 | ) 8 | 9 | func main() { 10 | ln, err := net.Listen("tcp", ":15440") 11 | if err != nil { // No ()s around cond 12 | fmt.Println("Error on listen: ", err) 13 | os.Exit(-1) 14 | } 15 | for { 16 | fmt.Println("Waiting for a connection via Accept") 17 | conn, err := ln.Accept() 18 | if err != nil { 19 | fmt.Println("Error on accept: ", err) 20 | os.Exit(-1) 21 | } 22 | 23 | fmt.Println("Reading once from connection") 24 | 25 | var buf [1024]byte 26 | n, err := conn.Read(buf[:]) 27 | if err != nil { 28 | fmt.Println("Error on read: ", err) 29 | os.Exit(-1) 30 | } 31 | 32 | fmt.Println("Client sent: ", string(buf[0:n])) 33 | conn.Close() 34 | } 35 | fmt.Println("Exiting") 36 | } 37 | -------------------------------------------------------------------------------- /04.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" // go fmt puts these in alphbetical order. 7 | ) 8 | 9 | func main() { 10 | ln, err := net.Listen("tcp", ":15440") 11 | if err != nil { // No ()s around cond 12 | fmt.Println("Error on listen: ", err) 13 | os.Exit(-1) 14 | } 15 | 16 | fmt.Println("Waiting for a connection via Accept") 17 | conn, err := ln.Accept() // note: Err doubly-declared. Careful. 18 | if err != nil { 19 | fmt.Println("Error on accept: ", err) 20 | os.Exit(-1) 21 | } 22 | 23 | fmt.Println("Reading once from connection") 24 | 25 | var buf [1024]byte 26 | n, err := conn.Read(buf[:]) // Note slicing! 27 | if err != nil { 28 | fmt.Println("Error on read: ", err) 29 | os.Exit(-1) 30 | } 31 | 32 | fmt.Println("Client sent: ", string(buf[0:n])) 33 | conn.Close() 34 | fmt.Println("Exiting") 35 | } 36 | -------------------------------------------------------------------------------- /07.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | ) 8 | 9 | // Go type inference is only partial: 10 | // we had to know what type Accept returned 11 | func handleConn(conn net.Conn) { 12 | fmt.Println("Reading once from connection") 13 | 14 | var buf [1024]byte 15 | n, err := conn.Read(buf[:]) 16 | if err != nil { 17 | fmt.Println("Error on read: ", err) 18 | os.Exit(-1) 19 | } 20 | 21 | fmt.Println("Client sent: ", string(buf[0:n])) 22 | conn.Close() 23 | } 24 | 25 | func main() { 26 | ln, err := net.Listen("tcp", ":15440") 27 | if err != nil { 28 | fmt.Println("Error on listen: ", err) 29 | os.Exit(-1) 30 | } 31 | for { 32 | fmt.Println("Waiting for a connection via Accept") 33 | conn, err := ln.Accept() 34 | if err != nil { 35 | fmt.Println("Error on accept: ", err) 36 | os.Exit(-1) 37 | } 38 | go handleConn(conn) 39 | } 40 | fmt.Println("Exiting") 41 | } 42 | -------------------------------------------------------------------------------- /13.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | type myMsg struct { 9 | seqNum int 10 | message string 11 | } 12 | 13 | func main() { 14 | fmt.Println("Go channels starting") 15 | 16 | ch1 := make(chan *myMsg) 17 | go chanSender(ch1, "cs1") 18 | 19 | ch2 := make(chan *myMsg) 20 | go chanSender(ch2, "cs2") 21 | 22 | for { 23 | select { 24 | case msg, ok := <-ch1: 25 | if ok { 26 | fmt.Println("CH1: ", msg.seqNum, ":", msg.message) 27 | } 28 | case msg, ok := <-ch2: 29 | if ok { 30 | fmt.Println("CH2: ", msg.seqNum, ":", msg.message) 31 | } else { 32 | fmt.Println("CH2 Closed") 33 | } 34 | } 35 | } 36 | } 37 | 38 | func chanSender(out chan<- *myMsg, prefix string) { 39 | seqNum := 0 40 | for i := 0; i < 5; i++ { 41 | time.Sleep(1*time.Second) 42 | out <- &myMsg{seqNum, fmt.Sprintf("%s: %s", prefix, "moo")} 43 | seqNum++ 44 | } 45 | close(out) 46 | } -------------------------------------------------------------------------------- /06.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" // go fmt puts these in alphbetical order. 7 | ) 8 | 9 | func main() { 10 | ln, err := net.Listen("tcp", ":15440") 11 | if err != nil { // No ()s around cond 12 | fmt.Println("Error on listen: ", err) 13 | os.Exit(-1) 14 | } 15 | for { 16 | fmt.Println("Waiting for a connection via Accept") 17 | conn, err := ln.Accept() 18 | if err != nil { 19 | fmt.Println("Error on accept: ", err) 20 | os.Exit(-1) 21 | } 22 | go func() { // Start a "goroutine" 23 | fmt.Println("Reading once from connection") 24 | 25 | var buf [1024]byte 26 | n, err := conn.Read(buf[:]) 27 | if err != nil { 28 | fmt.Println("Error on read: ", err) 29 | os.Exit(-1) 30 | } 31 | 32 | fmt.Println("Client sent: ", string(buf[0:n])) 33 | conn.Close() 34 | }() // note closing ()s here 35 | } 36 | fmt.Println("Exiting") 37 | } 38 | -------------------------------------------------------------------------------- /08.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | ) 8 | 9 | type myConn struct { 10 | conn net.Conn 11 | prefix string 12 | } 13 | 14 | func handleConn(mconn *myConn) { 15 | fmt.Println("Reading once from connection") 16 | 17 | var buf [1024]byte 18 | n, err := mconn.conn.Read(buf[:]) 19 | if err != nil { 20 | fmt.Println("Error on read: ", err) 21 | os.Exit(-1) 22 | } 23 | 24 | fmt.Println(mconn.prefix, ":", string(buf[0:n])) 25 | mconn.conn.Close() 26 | } 27 | 28 | func main() { 29 | ln, err := net.Listen("tcp", ":15440") 30 | if err != nil { 31 | fmt.Println("Error on listen: ", err) 32 | os.Exit(-1) 33 | } 34 | connNumber := 0 35 | for { 36 | fmt.Println("Waiting for a connection via Accept") 37 | conn, err := ln.Accept() 38 | if err != nil { 39 | fmt.Println("Error on accept: ", err) 40 | os.Exit(-1) 41 | } 42 | mconn := &myConn{ 43 | conn:conn, 44 | prefix: fmt.Sprintf("%d says", connNumber), 45 | } 46 | go handleConn(mconn) 47 | connNumber++ 48 | } 49 | fmt.Println("Exiting") 50 | } 51 | --------------------------------------------------------------------------------