2013-12-27 wcdj
大纲
本文总结GoLang中常用的几种函数用法,主要包括:
[0] 首先main是一个没有返回值的函数
[1] 普通函数
[2] 函数返回多个值
[3] 不定参函数
[4] 闭包函数
[5] 递归函数
[6] 类型方法, 类似C++中类的成员函数
[7] 接口和多态
[9] 错误处理, Defer接口
[10] 错误处理, Panic/Recover
测试代码
package main
import (
"fmt"
"math"
"errors"
"os"
"io"
)
///
func max(a int, b int) int {
if a > b {
return a
}
return b
}
func multi_ret(key string) (int, bool) {
m := map[string]int{"one":1, "two":2, "three":3}
var err bool
var val int
val, err = m[key]
return val, err
}
func sum(nums ...int) {
fmt.Print(nums, " ")
total := 0
for _, num := range nums {
total += num
}
fmt.Println(total)
}
func nextNum() func() int {
i, j := 0, 1
return func() int {
var tmp = i + j
i, j = j, tmp
return tmp
}
}
func fact(n int) int {
if n == 0 {
return 1
}
return n * fact(n-1)
}
// 长方形
type rect struct {
width, height float64
}
func (r *rect) area() float64 {
return r.width * r.height
}
func (r *rect) perimeter() float64 {
return 2 * (r.width + r.height)
}
// 圆形
type circle struct {
radius float64
}
func (c *circle) area() float64 {
return math.Pi * c.radius * c.radius
}
func (c *circle) perimeter() float64 {
return 2 * math.Pi * c.radius
}
// 接口
type shape interface {
area() float64
perimeter() float64
}
func interface_test() {
r := rect{width: 2, height: 4}
c := circle{radius: 4.3}
// 通过指针实现
s := []shape{&r, &c}
for _, sh := range s {
fmt.Println(sh)
fmt.Println(sh.area())
fmt.Println(sh.perimeter())
}
}
type myError struct {
arg int
errMsg string
}
// 实现error的Error()接口
func (e *myError) Error() string {
return fmt.Sprintf("%d - %s", e.arg, e.errMsg)
}
func error_test(arg int) (int, error) {
if arg < 0 {
return -1, errors.New("Bad Arguments, negtive")
} else if arg > 256 {
return -1, &myError{arg, "Bad Arguments, too large"}
}
return arg * arg, nil
}
func CopyFile(dstName, srcName string) (written int64, err error) {
src, err := os.Open(srcName)
if err != nil {
fmt.Println("Open failed")
return
}
defer src.Close()
dst, err := os.Create(dstName)
if err != nil {
fmt.Println("Create failed")
return
}
defer dst.Close()
// 注意dst在前面
return io.Copy(dst, src)
}
//
func main() {
// [0] 首先main是一个没有返回值的函数
// [1] 普通函数
fmt.Println(max(1, 100))
// [2] 函数返回多个值
v, e := multi_ret("one")
fmt.Println(v, e)
v, e = multi_ret("four")
fmt.Println(v, e)
// 典型的判断方法
if v, e = multi_ret("five"); e {
fmt.Println("OK")
} else {
fmt.Println("Error")
}
// [3] 不定参函数
sum(1, 2)
sum(2, 4, 5)
nums := []int{1, 2, 3, 4, 5}
sum(nums...)
// [4] 闭包函数
nextNumFunc := nextNum()
for i := 0; i < 10; i++ {
fmt.Println(nextNumFunc())
}
// [5] 递归函数
fmt.Println(fact(4))
// [6] 类型方法, 类似C++中类的成员函数
r := rect{width: 10, height: 15}
fmt.Println("area: ", r.area())
fmt.Println("perimeter: ", r.perimeter())
rp := &r
fmt.Println("area: ", rp.area())
fmt.Println("perimeter: ", rp.perimeter())
// [7] 接口和多态
interface_test()
// [8] 错误处理, Error接口
for _, val := range []int{-1, 4, 1000} {
if r, e := error_test(val); e != nil {
fmt.Printf("failed: %d:%s\n", r, e)
} else {
fmt.Println("success: ", r, e)
}
}
// [9] 错误处理, Defer接口
if w, err := CopyFile("/data/home/gerryyang/dst_data.tmp", "/data/home/gerryyang/src_data.tmp"); err != nil {
fmt.Println("CopyFile failed: ", e)
} else {
fmt.Println("CopyFile success: ", w)
}
// 你猜下面会打印什么内容
fmt.Println("beg ------------")
for i := 0; i < 5; i++ {
defer fmt.Printf("%d ", i)
}
fmt.Println("end ------------")
// [10] 错误处理, Panic/Recover
// 可参考相关资料, 此处省略
}
/*
output:
100
1 true
0 false
Error
[1 2] 3
[2 4 5] 11
[1 2 3 4 5] 15
1
2
3
5
8
13
21
34
55
89
24
area: 150
perimeter: 50
area: 150
perimeter: 50
&{2 4}
8
12
&{4.3}
58.088048164875275
27.01769682087222
failed: -1:Bad Arguments, negtive
success: 16 <nil>
failed: -1:1000 - Bad Arguments, too large
CopyFile success: 8
------------
------------
4 3 2 1 0
*/
参考
发现耗子叔叔两篇不错的GoLang入门文章,真是坐车和上厕所必备精品。
[1] Go 语言简介(上)— 语法
[2] Go 语言简介(下)— 特性