Go: Hello World III
Tags: go
Functions
package main
import (
"fmt"
)
// add adds a to b
func add(a int, b int) int {
return a + b
}
// divmod return quotient and reminder
func divmod(a int, b int) (int, int) {
return a / b, a % b
}
func main() {
val := add(1, 2)
fmt.Println(val)
// 3
div, mod := divmod(7, 2)
fmt.Printf("div = %d, mode = %d", div, mod)
// div = 3, mode = 1
}
-
params passing
- Go pass integer to a func: it passese by value, which means it will copy it then pass into func. 不會改變原本的變數
- Go pass
slices
ormap
: passing by reference. func 裡面運作的就是原本的 object!!
func doubleAt(values []int, i int) {
values[i] *=2
}
func double(n int) {
n *= 2
}
func main() {
values := []int{1, 2, 3, 4}
doubleAt(values, 2)
fmt.Println(values)
// [1 2 6 4]
val := 10
double(10)
fmt.Println(val)
// 10
}
-
用 pointer 可以解決傳 integer 的 copy by value 狀況
-
func doublePtr(n *int) { *n *=2 }
-
doublePtr(&val) fmt.Println(val) // 20 fmt.Println(&val) // 0xc0000100c8
-
func doubleAt(values []int, i int) {
values[i] *=2
}
func double(n int) {
n *= 2
}
func doublePtr(n *int) {
*n *=2
}
func main() {
values := []int{1, 2, 3, 4}
doubleAt(values, 2)
fmt.Println(values)
// [1 2 6 4]
val := 10
double(10)
fmt.Println(val)
// 10
doublePtr(&val)
fmt.Println(val)
// 20
fmt.Println(&val)
// 0xc0000100c8
}
-
Error return
- go func can return more than one value
nil
package main
import (
"fmt"
"math"
)
func sqrt(n float64) (float64, error) {
if n < 0 {
return 0.0, fmt.Errorf("sqrt of negative value (%f)", n)
}
return math.Sqrt(n), nil
}
func main() {
s1, err := sqrt(2.0)
if err != nil {
fmt.Printf("ERROR: %s\n", err)
} else {
fmt.Println(s1)
}
// 1.4142135623730951
s2, err2 := sqrt(-2.0)
if err2 != nil {
fmt.Printf("ERROR: %s\n", err2)
} else {
fmt.Println(s2)
}
// ERROR: sqrt of negative value (-2.000000)
}
-
defer
- go has its garbage collector
defer
: make sure resources is closed / free
func cleanup(name string) {
fmt.Printf("Cleaning up %s\n", name)
}
func worker() {
defer cleanup("A")
defer cleanup("B")
fmt.Println("worker")
}
func main() {
worker()
// worker
// Cleaning up B
// Cleaning up A
}
Challenge: Functions
-
Write a function that gets a URL and returns the value of Content-Type response HTTP header
-
The function should return an error if it can’t perform a GET request
-
func contentType(url string) (string, error)
- Use
net/http
Get function to make HTTP call- resp, err := http.Get(“https:/golang.org”)
- Use
res.Header.Get
to get the value of a header- resp.Header.Get(“Content-Length”)
-
Maker sure the response body is closed
- resp.Body.Close()
我的解
package main
import (
"fmt"
"net/http"
)
func contentType(url string) (string, error) {
resp, err := http.Get(url)
defer resp.Body.Close()
if err != nil {
return "error", fmt.Errorf("Error: %s\n", err)
} else {
result := resp.Header.Get("Content-Type")
fmt.Printf("type: %T\n", result)
return result, nil
}
}
func main() {
sr, err := contentType("https://golang.org")
fmt.Println("content-type: ", sr ,"\n", "Error:", err)
}
// type: string
// content-type: text/html; charset=utf-8
// Error: <nil>
老師的解
package main
import (
"fmt"
"net/http"
)
func contentType(url string) (string, error) {
resp, err := http.Get(url)
if err != nil {
return "", err
}
defer resp.Body.Close() // Make sure we close the body
ctype := resp.Header.Get("Content-Type")
if ctype == "" { // Return error if Content-Type header not found
return "", fmt.Errorf("can't find Content-Type header")
}
return ctype, nil
}
func main() {
ctype, err := contentType("https://linkedin.com")
if err != nil {
fmt.Printf("ERRPR: %s\n", err)
} else {
fmt.Println(ctype)
}
}
// text/html; charset=utf-8