mirror of
https://github.com/unknwon/the-way-to-go_ZH_CN.git
synced 2025-08-19 20:00:35 +08:00
ch10.6.1 OK
This commit is contained in:
148
eBook/10.6.md
148
eBook/10.6.md
@@ -19,7 +19,155 @@ func (a *denseMatrix) Add(b Matrix) Matrix
|
|||||||
func (a *sparseMatrix) Add(b Matrix) Matrix
|
func (a *sparseMatrix) Add(b Matrix) Matrix
|
||||||
```
|
```
|
||||||
|
|
||||||
|
alias类型不能有它原始类型上已经定义过的方法。
|
||||||
|
|
||||||
|
定义方法的一般格式如下:
|
||||||
|
|
||||||
|
func (recv receiver_type) methodName(parameter_list) (return_value_list) { ... }
|
||||||
|
|
||||||
|
在方法名之前,func关键字之后的括号中指定receiver。
|
||||||
|
|
||||||
|
如果recv是receiver的实例,Method1是它的方法名,那么方法调用遵循传统的object.name选择器符号:**recv.Method1()**
|
||||||
|
|
||||||
|
如果recv一个指针,Go会自动解引用。
|
||||||
|
|
||||||
|
如果方法不需要使用recv的值,可以用*_*替换它,比如:
|
||||||
|
|
||||||
|
func (_ receiver_type) methodName(parameter_list) (return_value_list) { ... }
|
||||||
|
|
||||||
|
recv就像是OO语言中的this或self,但是Go中并没有这两个关键字。随个人喜好,你可以使用this或self作为receiver的名字。下面是一个结构体上的简单方法的例子:
|
||||||
|
|
||||||
|
Listing 10.10—method .go
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type TwoInts struct {
|
||||||
|
a int
|
||||||
|
b int
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
two1 := new(TwoInts)
|
||||||
|
two1.a = 12
|
||||||
|
two1.b = 10
|
||||||
|
|
||||||
|
fmt.Printf("The sum is: %d\n", two1.AddThem())
|
||||||
|
fmt.Printf("Add them to the param: %d\n", two1.AddToParam(20))
|
||||||
|
|
||||||
|
two2 := TwoInts{3, 4}
|
||||||
|
fmt.Printf("The sum is: %d\n", two2.AddThem())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tn *TwoInts) AddThem() int {
|
||||||
|
return tn.a + tn.b
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tn *TwoInts) AddToParam(param int) int {
|
||||||
|
return tn.a + tn.b + param
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
输出:
|
||||||
|
|
||||||
|
The sum is: 22
|
||||||
|
Add them to the param: 42
|
||||||
|
The sum is: 7
|
||||||
|
|
||||||
|
下面是非结构体类型上方法的例子:
|
||||||
|
|
||||||
|
Listing 10.11—method2.go:
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type IntVector []int
|
||||||
|
|
||||||
|
func (v IntVector) Sum() (s int) {
|
||||||
|
for _, x := range v {
|
||||||
|
s += x
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(IntVector{1, 2, 3}.Sum()) // 输出是6
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
** 练习 10.6: employee_salary.go
|
||||||
|
|
||||||
|
定义结构体employee,它有一个salary字段,给这个结构体定义一个方法giveRaise来按照指定的百分比增加薪水。
|
||||||
|
|
||||||
|
** 练习 10.7: iteration_list.go
|
||||||
|
|
||||||
|
下面这段代码有什么错?
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "container/list"
|
||||||
|
|
||||||
|
func (p *list.List) Iter() {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
lst := new(list.List)
|
||||||
|
for _= range list.Iter() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
类型和作用在它上面定义的方法必须在同一个包里定义,这就是为什么不能在int、float或类似这些的类型上定义方法。试图在int类型上定义方法会得到一个编译错误:
|
||||||
|
|
||||||
|
cannot define new methods on non-local type int
|
||||||
|
|
||||||
|
比如想在time.Time上定义如下方法:
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (t time.Time) first3Chars() string {
|
||||||
|
return time.LocalTime().String()[0:3]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
类型在在其他的,或是非本地的包里定义,在它上面定义方法都会得到和上面同样的错误。
|
||||||
|
|
||||||
|
但是有一个绕点的方式:可以先定义该类型(比如int,float)的别名类型,然后再为别名类型定义方法。或者像下面这样将它作为匿名类型嵌入在一个新的结构体中。当然方法只在这个别名类型上有效。
|
||||||
|
|
||||||
|
Listing 10.12—method_on_time.go:
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type myTime struct {
|
||||||
|
time.Time //anonymous field
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t myTime) first3Chars() string {
|
||||||
|
return t.Time.String()[0:3]
|
||||||
|
}
|
||||||
|
func main() {
|
||||||
|
m := myTime{time.Now()}
|
||||||
|
// 调用匿名Time上的String方法
|
||||||
|
fmt.Println("Full time now:", m.String())
|
||||||
|
// 调用myTime.first3Chars
|
||||||
|
fmt.Println("First 3 chars:", m.first3Chars())
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output:
|
||||||
|
Full time now: Mon Oct 24 15:34:54 Romance Daylight Time 2011
|
||||||
|
First 3 chars: Mon
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
## 链接
|
## 链接
|
||||||
- [目录](directory.md)
|
- [目录](directory.md)
|
||||||
|
Reference in New Issue
Block a user