Go语言中同时有函数和方法!

函数: go程序必须要包含一个main函数。main函数不能有任何参数和返回值!

1. 定义方法示例:

func max(num1, num2 int) int {    // 形参类型相同时,可以只写一个类型
// 后面的int代表返回值类型
/* 定义局部变量 */
var result int
if (num1 > num2) {
result = num1
} else {
result = num2
}
return result
}
------------------------------------------
func sssss(x int, y string) (string, int) {
return y, x
}
------------------------------------------
func SumAndProduct(A, B int) (Add int, Multiplied int) {
Add = A+B
Multiplied = A*B
return
}
--------------------------------------------------------------
×××××× import(
"fmt"
"math"
)
/* 声明函数变量 */
getSquareRoot := func(x float64) float64 {return math.Sqrt(x)}
/* 使用函数 */
fmt.Println(getSquareRoot(9))

  

2. 当函数有多个返回值时,也可以使用空白标识符 _ 来丢弃某个/些值。

3. 可变参——接受变参的函数是有着形参数量不确定的函数。。。

定义方法:

    func func_name(arg ...int) {} // 这里arg ...int标志此函数可以接收不定数量的int类型的实参

                  // 在函数体中,arg是一个int类型的切片(arg也可以换成args)

4. 参数传递——值传递和引用传递

值传递——就是普通的值传递啊。。

引用传递——使用指针——实质也是值传递。。。

var x int = 2 则若实参为地址 &x, 则形参为 *int 型。 传内存地址比较轻量级(8bytes),我们可以用指针传递体积大的结构体。 如果用参数值传递的话, 在每次copy上面就会花费相对较多的系统开销(内存和时间)。 所以当你要传递大的结构体的时候,用指针是一个明智的选择。

5 闭包: Go语言支持匿名函数,闭包的表现形式一般是匿名函数,通过函数返回一个函数。 闭包会使函数中的变量都被保存在内存中!消耗内存。

×××只要闭包还在使用,那么被闭包引用的变量就会一直存在!!!

func getSequence() func() int {
i := 0
return func() int {
i += 1
return i
}
} func main() {
/* nextNumber 为一个函数 */
// var nextNumber = getSequence() 或者
    nextNumber := getSequence() /* 调用 nextNumber 函数,i 变量自增 1 并返回 */
fmt.Println(nextNumber())
fmt.Println(nextNumber())
fmt.Println(nextNumber())

/* 创建新的函数 nextNumber1,并查看结果 */
nextNumber1 := getSequence()
fmt.Println(nextNumber1())
fmt.Println(nextNumber1())
}

打印结果:
1
2
3
1
2

  

6. 可以声明一个函数类型;然后函数就可以作为值传递了! type testInt func(int) bool   // 声明了一个函数类型testInt, 接收一个int型参数,返回值为bool类型

7. panic和recover: Go语言没有像Java那样的异常机制,不能抛出异常,而是使用panic和recover机制。 panic(...)——当函数F调用panic,函数F的执行被中断,但是F中的延迟函数会正常执行,然后F返回到调用它的地方。在调用的地方,F的行为就像调用了panic。这一过程继续向上,直到发生panic的goroutine中所有调用的函数返回,此时程序退出。

recover()让进入恐慌的goroutine恢复过来。recover仅在延迟函数中有效。在正常的执行过程中,调用recover会返回nil,并且没有其它任何效果。


方法:

1. 定义方法: func (t Type) method(parameter list) { //其中t是一个接收器,可以接收结构体或者非结构体类型 ... }

示例代码:
package main
import "fmt" ​
type Employee struct {
name string
salary int
currency string
}

/*
  displaySalary()的方法接收器为Employee结构体类型
*/
func (e Employee) displaySalary() {
fmt.Printf("Salary of %s is %s%d", e.name, e.currency, e.salary)
}

func main() {
emp1 := Employee {
name: "Sam Adolf",
salary: 5000,
currency: "$",
}
emp1.displaySalary() // 调用displaySalary() 方法
}

可以定义相同的方法名:相同名称的方法可以在不同的类型上定义,而具有相同名称的函数是不允许的!

package main
import (
"fmt"
"math"
)
type Rectangle struct {
width, height float64
}
type Circle struct {
radius float64
}
// 该 method 属于 Rectangle 类型对象中的方法
func (r Rectangle) area() float64 {
return r.width * r.height
}
// 该 method 属于 Circle 类型对象中的方法
func (c Circle) area() float64 {
return c.radius * c.radius * math.Pi
}
func main() {
r1 := Rectangle{12, 2}
r2 := Rectangle{9, 4}
c1 := Circle{10}
c2 := Circle{25}
fmt.Println("Area of r1 is: ", r1.area())
fmt.Println("Area of r2 is: ", r2.area())
fmt.Println("Area of c1 is: ", c1.area())
fmt.Println("Area of c2 is: ", c2.area())
}

  

2. 变量作用域:
       函数内定义的变量称为局部变量,它们的作用域只在函数体内(参数和返回值变量也是局部变量)
       函数外定义的变量称为全局变量,首字母大写全局变量可以在整个包甚至外部包(被导出后)使用
  ​
3. 用指针可以改变值!!

package main
import (
"fmt"
)

type Rectangle struct {
width, height int
}

func (r *Rectangle) setVal() {
r.height = 20
}

func main() {
p := Rectangle{1, 2}
s := p // 此时只是将p的数据拷贝给s了一份,即二者并不是指向同一数据的关系
// p是p,s是s,改变p不会影响s
p.setVal()
mt.Println(p.height, s.height)
}

4. 继承: 如果匿名字段实现了一个method,那么包含这个匿名字段的struct也能调用该method.

type Human struct {
name string
age int
phone string
}
type Student struct {
Human // 匿名字段
school string
}
type Employee struct {
Human //匿名字段
company string
}

func (h *Human) SayHi() {
fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
}
func main() {
mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"}
sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"}
mark.SayHi()
sam.SayHi()
}

  


5. 重写: (就近原则)

package main

import "fmt"
type Human struct {
name string
age int
phone string
}
type Student struct {
Human //匿名字段
school string
}
type Employee struct {
Human //匿名字段
company string
}
//Human定义method
func (h *Human) SayHi() {
fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
}
//Employee的method重写Human的method
func (e *Employee) SayHi() {
fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n", e.name,
         e.company, e.phone) // Yes you can split into 2 lines here.
}
func main() {
mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"}
sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"}
mark.SayHi()
sam.SayHi()
}

结果:
Hi, I am Mark you can call me on 222-222-YYYY
Hi, I am Sam, I work at Golang Inc. Call me on 111-888-XXXX

  

Go语言学习笔记(7)——函数和方法的更多相关文章

  1. Go语言学习笔记(五) [函数]

    日期:2014年7月29日   1.函数定义:func (p type) funcname(q int) (r,s int) {return 0,0 }     func: 保留字,用于定义一个函数 ...

  2. 【Go语言学习笔记】函数做参数和闭包

    函数做参数 在Go语言中,函数也是一种数据类型,我们可以通过type来定义它,它的类型就是所有拥有相同的参数,相同的返回值的一种类型.类似于重写(同名覆盖). 回调函数:函数有一个参数是函数类型,这个 ...

  3. C语言学习笔记--字符串函数

    字符串函数 需要包含头文件#include<stdio.h> strlen strcmp strcpy strchr strstr strcasestr

  4. python学习笔记之函数(方法)(四)

    一.函数是什么? 函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的,编程中的函数在英文中也有很多不同的叫法.在C中叫function,在Java里面叫做method. 定义: ...

  5. C语言学习笔记之函数指针与函数指针数组

    指针函数:本质是一个函数: 是一个返回指针类型的函数int * sum(){ } 函数指针:本质是一个指针: 是一个指向函数的指针 int (*p)(int,int) = sum; p(5,6); i ...

  6. scala学习笔记:函数与方法

    http://stackoverflow.com/questions/2529184/difference-between-method-and-function-in-scala A Functio ...

  7. Go语言学习笔记七: 函数

    Go语言学习笔记七: 函数 Go语言有函数还有方法,神奇不.这有点像python了. 函数定义 func function_name( [parameter list] ) [return_types ...

  8. 大一C语言学习笔记(5)---函数篇-定义函数需要了解注意的地方;定义函数的易错点;详细说明函数的每个组合部分的功能及注意事项

    博主学习C语言是通过B站上的<郝斌C语言自学教程>,对于C语言初学者来说,我认为郝斌真的是在全网C语言学习课程中讲的最全面,到位的一个,这个不是真不是博主我吹他哈,大家可以去B站去看看,C ...

  9. 2017-04-21周C语言学习笔记

    C语言学习笔记:... --------------------------------- C语言学习笔记:学习程度的高低取决于.自学能力的高低.有的时候生活就是这样的.聪明的人有时候需要.用笨的方法 ...

随机推荐

  1. python3编程基础之一:操作

    基本操作有:读数据.写数据.运算.控制.输入.输出.语句块 1.读取数据: num1 = 50 num2 = num1 //通过num2取得num1的值,这就是逻辑上的读取 测试数据:print(nu ...

  2. IDEA的版本控制

    参考:https://blog.csdn.net/qq_35246620/article/details/70792861 1.从远程仓库下载项目 2.提交项目到远程仓库

  3. Macbook上打开多个终端的方法

    方法有如下两种 1.首先是的焦点在终端上(使用鼠标点击下终端).然后使用快捷键command+N 即可得到另一个终端界面. (如果现在光标的焦点在浏览器上,那么就是新打开一个浏览器窗口) 2.同样,光 ...

  4. keras输出预测值和真实值

    在使用keras搭建神经网络时,有时需要查看一下预测值和真是值的具体数值,然后可以进行一些其他的操作.这几天查阅了很多资料.好像没办法直接access到训练时的数据.所以我们可以通过回调函数,传入新的 ...

  5. window.open()详解及浏览器兼容性问题示例探讨

    这篇文章主要介绍了window.open()的使用及浏览器兼容性问题方面的知识,感兴趣的朋友可以参考下   一.基本语法: window.open(pageURL,name,parameters) 其 ...

  6. C语言练习,可以解析协议,主机,路径,询问,片段等

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> ...

  7. 010-多线程-JUC集合-Queue-ConcurrentLinkedQueue

    一.概述 ConcurrentLinkedQueue是线程安全的队列,它适用于“高并发”的场景. 它是一个基于链接节点的无界线程安全队列,按照 FIFO(先进先出)原则对元素进行排序.队列元素中不可以 ...

  8. ubuntu server 18.04 有线网卡默认关闭,需要手工配置才能使用的方法

    1.安装完ubuntu server 18.04 后,笔记本电脑的有线网卡已经识别了,但是没有ip, 并且插上网线后端口灯不亮. 解决方法: 第一步.配置端口链路状态为 up # ip link se ...

  9. linuxan安装redis出现Newer version of jemalloc required错误

    linux安装redis执行make命令时出现问题 解决方法 make MALLOC=libc 如果要指定安装文件夹 使用命令:make PREFIX  = /usr/local/redis(文件夹路 ...

  10. 采购订单审批与撤销审批BAPI

    *"---------------------------------------------------------------------- *"*"本地接口: *& ...