GoLang之各种函数的用法

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,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,1000} {
		if r,e := error_test(val); e != nil {
			fmt.Printf("Failed: %d:%s\n",r,e)
		} else {
			fmt.Println("success: ",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 语言简介(下)— 特性

相关文章

什么是Go的接口? 接口可以说是一种类型,可以粗略的理解为他...
1、Golang指针 在介绍Golang指针隐式间接引用前,先简单说下...
1、概述 1.1&#160;Protocol buffers定义 Protocol buffe...
判断文件是否存在,需要用到"os"包中的两个函数: os.Stat(...
1、编译环境 OS :Loongnix-Server Linux release 8.3 CPU指...
1、概述 Golang是一种强类型语言,虽然在代码中经常看到i:=1...