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. qt 关于Qt中MVC的介绍与使用

    Qt包含一组使用模型/视图结构的类,可以用来管理数据并呈现给用户.这种体系结构引入的分离使开发人员更灵活地定制项目,并且提供了一个标准模型的接口,以允许广泛范围的数据源被使用到到现有的视图中. 模型 ...

  2. THINKPHP扩展PHPEXCEL,PHP7.2以上版本无法导出Excel

     THINKPHP扩展PHPEXCEL与PHP7.3高版本兼容问题 框架:THINKPHP5,PHPEXCEL版本:1.81 无法导出EXCEL原因为Shared/OLE.php第290行使用cont ...

  3. Linux | Vim使用

    Linux vi/vim 所有的 Unix Like 系统都会内建 vi 文书编辑器,其他的文书编辑器则不一定会存在. 但是目前我们使用比较多的是 vim 编辑器. vim 具有程序编辑的能力,可以主 ...

  4. hystrix流程图收藏

    最近在看张开涛的亿级流量的书,学习了一个新的防雪崩的功能hystrix,在学习这个功能的过程中,看了一些网站也温习了一些知识,例如double_check locking功能,还有cache的击穿作为 ...

  5. 贝济埃曲线quadTo与传统的手势轨迹平滑度对比分析

    package com.loaderman.customviewdemo; import android.content.Context; import android.graphics.Canvas ...

  6. python开发-实现redis中的发布订阅功能

    Python3学习(二十七):python实现Redis的订阅与发布(sub-pub机制) 先介绍一下redis的pub/sub功能: Pub/Sub功能(means Publish, Subscri ...

  7. web端安全测试工具

    https://www.cnblogs.com/ios9/p/7692373.html 十大web安全扫描工具 扫描程序可以在帮助造我们造就安全的Web 站点上助一臂之力,也就是说在黑客“黑”你之前, ...

  8. Apache三种工作模式详解

    Apache HTTP服务器被设计为一个强大的.灵活的能够在多种平台以及不同环境下工作的服务器.这种模块化的设计就叫做“多进程处理模块”(Multi-Processing Module,MPM),也叫 ...

  9. 原创:Mac AppleScript 自动登录两个QQ

    前提,已有登录过的账号,且没有设置为自动登录 tell application "QQ" activate tell application "System Events ...

  10. 基于Docker+Jenkins实现自动化部署

    使用码云搭建Git代码存储仓库 https://gitee.com/login 使用码云创建私有私有git仓库 将本地springboot项目上传到git仓库中 基于Docker安装Jenkins环境 ...