字符串
与其它主要编程语言的差异
Unicode UTF8
编码与存储
字符 | "中" |
---|---|
Unicode | 0x4E2D |
UTF-8 | 0xE4B8AD |
string/[]byte | [0xE4, 0xB8, 0xAD] |
常用字符串函数
函数:一等公民
与其它主要编程语言的差异
学习函数式编程
函数: 可变参数及defer
可变参数
func sum(ops ...int) int {
s := 0
for _, op := range ops {
s += op
}
return s
}
defer 函数
func TestDefer(t *testing.T) {
defer func() {
t.Log("Clear resources")
}()
t.Log("Started")
panic("Fatal error") //defer仍会执行
}
封装数据和行为
结构体定义
type Employee struct {
Id string
Name string
Age int
}
实例创建及初始化
e := Employee{"0", "Bob", 20}
e1 := Employee{Name: "Mike", Age: 30}
e2 := new(Employee) //注意这里返回的引用/指针,相当于 e := &Employee{}
e2.Id = "2" //与其它主要编程语言的差异:通过实例的指针访问成员不需要使用->
e2.Age = 22
e2.Name = "Rose"
行为(方法)定义
与其它主要编程语言的差异
type Employee struct {
Id string
Name string
Age int
}
//第一种定义方式在实例对应方法被调用时,实例的成员会进行值复制
func (e Employee) String() string {
return fmt.Sprintf("ID:%s-Name:%s-Age:%d", e.Id, e.Name, e.Age)
}
//通常情况下为避免内存拷贝我们使用第二种定义方式
func (e *Employee) String() string {
return fmt.Sprintf("ID:%s/Name:%s/Age:%d", e.Id, e.Name, e.Age)
}
Duck Type 式接口实现
//接口定义
type Programmer interface {
WriteHelloWorld() Code
}
//接口实现
type GoProgrammer struct {
}
func (p *GoProgrammer) WriteHelloWorld() Code {
return "fmt.Println(\"Hello World!\")"
}
Go 接口
与其它主要编程语言的差异
接口变量
自定义类型
1. type IntConvertionFn fun(n int) int
2. type MyPoint int
多态
空接口与断言
v, ok := p.(int) //ok=true 时为转换成功
Go接口最佳实践
倾向于使用小的接口定义,很多接口只包含一个方法
type Reader interface {
Read(p []byte)(n int, err error)
}
type Writer interface {
Write(p []byte)(n int, err error)
}
较大的接口定义,可以由多个小接口定义组合而成
type ReadWriter interface {
Reader
Writer
}
只依赖于必要功能的最小接口
func StoreData(reader Reader) error {
...
}
Go的错误机制
与其它主要编程语言的差异
type error interface {
Error() string
}
errors.New("n must be in the range[0, 11]")
最佳实践
定义不同的错误变量,以便于判断错误类型
var LessThanTwoError error = errors.New("n must be greater than 2")
var GreaterThanHundredError error = errors.New("n must be less than 100")
...
func TestGetFibonacci(t *testing.T) {
var list []int
list, err := GetFibonacci(-10)
if err == LessThanTwoError {
t.Error("Need a larger number")
}
if err == GreaterThanHundredError {
t.Error("Nedd a larger number")
}
}
及早失败,避免嵌套
panic
panic vs os.Exit
recover
/* !< java */
try {
...
} catch(Throwable t) {
}
/* !< C++ */
try {
...
} catch(...) {
}
/* !< golang */
defer func() {
if err := recover(); err != nil {
//恢复错误
}
}()
最常见的"错误恢复"
defer func {
if err := recover(); err != nil {
log.Error("recoverd panic", err)
}
}()
//这种错误修复非常危险
当心! recover成为恶魔
原文:https://www.cnblogs.com/xuzhaoping/p/11602069.html