惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

U
Unit 42
N
News and Events Feed by Topic
S
Schneier on Security
G
GRAHAM CLULEY
Scott Helme
Scott Helme
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
GbyAI
GbyAI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
C
CERT Recently Published Vulnerability Notes
T
The Exploit Database - CXSecurity.com
C
Cisco Blogs
T
The Blog of Author Tim Ferriss
Cisco Talos Blog
Cisco Talos Blog
P
Privacy & Cybersecurity Law Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
博客园 - 司徒正美
Blog — PlanetScale
Blog — PlanetScale
Project Zero
Project Zero
MyScale Blog
MyScale Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
The Last Watchdog
The Last Watchdog
Vercel News
Vercel News
The Cloudflare Blog
C
Check Point Blog
Help Net Security
Help Net Security
Microsoft Security Blog
Microsoft Security Blog
AI
AI
Simon Willison's Weblog
Simon Willison's Weblog
云风的 BLOG
云风的 BLOG
M
MIT News - Artificial intelligence
Stack Overflow Blog
Stack Overflow Blog
腾讯CDC
NISL@THU
NISL@THU
S
Security @ Cisco Blogs
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
S
SegmentFault 最新的问题
MongoDB | Blog
MongoDB | Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Threatpost
AWS News Blog
AWS News Blog
Cloudbric
Cloudbric
N
News and Events Feed by Topic
PCI Perspectives
PCI Perspectives
S
Securelist
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
V
Vulnerabilities – Threatpost
S
Secure Thoughts

博客园 - 悉野

ssh连结vmware中ubuntu的共享文件夹 spring加载冲突问题 spring一个错误修正 抓安卓日记到文件 注册表删除桌面顽固图标 github买的账号无法拉取代码的解决方法 apk常用命令 java服务器异常处理 ES6 学习难度分层 promise原理 材质, 纹理, shader之间的关系 TCP与UDP区别 javascript中=>与function的区别 javascript中函数解析过程 cocos使用fgui 几种服务注册与发现的区别 mybatis测试 向量点乘与叉乘 unity画布3种渲染模式 go学习笔记10(HTTP) go学习笔记9(TCP) go学习笔记8(反射) c++简单的线程池 operator new 是 C++ 动态内存分配的核心函数,负责分配原始内存,不调用构造函数 C++的定位放置new(Placement new) go学习笔记7(泛型,文件读写,测试) go学习笔记6(协程与channel,select使用,线程安全,异常处理) go学习笔记4(数组与切片,map,if,switch,for循环) go学习笔记3(变量定义,输入输出,基本数据类型) go学习笔记2 laya打包的apk版本更新脚本 laya列表滚动问题 laya踩坑记 laya列表时计算具体体子项是列表中第几个 子弹射击 laya给自己画边框 查看laya已经加载的资源 laya spine事件
go学习笔记5(函数,结构体,自定义类型和类别名,接口)
悉野 · 2026-04-05 · via 博客园 - 悉野

8.函数

package main

import (
    "fmt"
    "time"
)

func init() {
    fmt.Println("init1")
}
func init() {
    fmt.Println("init2")
}

// 无返回值
func say(name, msg string) {
    fmt.Println(name, msg)
}

// 指定类型返回值
func add(numList ...int) int {
    var sum int
    for _, num := range numList {
        sum += num
    }
    return sum
}

// 多个返回值
func fun1() (int, string) {
    return 1, "hello"
}

// 命名返回值
func func2() (OK bool) {
    OK = true
    return OK
}

// 高阶函数 1.接收一个函数作为参数 2.或者返回一个函数
func awaitAdd(waitSeconds int) func(numList ...int) int {
    //time.Second是Duration类型的, 本质是int64, waitSeconds是int类型的不允许隐式转换, 可以用time.Duration来显示转换
    time.Sleep(time.Duration(waitSeconds) * time.Second)
    return func(numList ...int) int {
        //闭包 可以访问外层的变量waitSeconds
        //time.Sleep(time.Duration(waitSeconds) * time.Second)
        sum := 0
        for _, num := range numList {
            sum += num
        }
        return sum
    }
}

func main() {
    say("Tom", "hello world")
    sum := add(5, 6, 7, 8)
    fmt.Println(sum)

    var getName = func(name string) string {
        return name
    }

    fmt.Println(getName("Tom"))
    var login = func() {
        fmt.Println("login func")
    }
    var register = func() {
        fmt.Println("register func")
    }
    // 映射函数
    funcMap := map[int]func(){
        1: login,
        2: register,
    }
    index := 1
    function, ok := funcMap[index]
    if ok {
        function()
    }
    start := time.Now()
    sum = awaitAdd(2)(1, 2, 3)
    // 计算时间差
    subTime := time.Since(start)
    fmt.Println(sum, subTime)
    // 取地址, 取值, 只有指针概念, 指针不能运算, 如p++之类的没有,没有引用概念,
    var test = "name"
    var tmp = &test
    *tmp = "new name"
    // 在return之前调用, 哪个写在后面, 哪个先调用, 压入的
    defer fmt.Println("defer1")
    defer fmt.Println("defer2")

    fmt.Println(test)

}


9.结构体

package main

import (
    "encoding/json"
    "fmt"
)

type Class struct {
    // 首字母大写, 可以包导出, 在其它包中可使用
    Name string
}
type Student struct {
    // 首字母小写, 只能本包中使用
    name      string `json:"name"` //配置json的Tag, 转成json时就是指定的名字了
    ClassName Class  `json:"className"`
    Test      int    `json:"test"`
    Password  string `json:"-"`             //这个字段不会转成json
    Age       int    `json:"age,omitempty"` //如果这个字段为空值, 此字段就不转json
    // 或者直接写Class, 一个类型名称就行了
}

// 值传递, 复制了整个Student结构
func (stu Student) SetName(name string) {
    fmt.Printf("SetName中stu的指针%p\n", &stu)
    stu.name = name
}

// 指针传递
// 警告说有值方法, 又有指针方法, Struct Student has methods on both value and pointer receivers. Such usage is not recommended by the Go Documentation.
func (stu *Student) SetName2(name string) {
    fmt.Printf("SetName2中stu的指针%p\n", stu)
    stu.name = name
}

type Animal struct {
    Name string
}
type Cat struct {
    Animal
}

func main() {
    var stu = Student{name: "Tom", ClassName: Class{"一年级"}}
    fmt.Printf("main中stu的指针%p\n", &stu)
    stu.ClassName.Name = "二年级"
    stu.SetName("newName")
    // 值传递不会改到stu的name, 里面修改的复制对象
    fmt.Println(stu)
    // 指针传递
    stu.SetName2("newName2")
    fmt.Println(stu)

    var cat Cat
    // 可以直接取对应成员的成员变量, 相当继承
    cat.Name = "cat"
    // 转成json
    byteData, err := json.Marshal(stu)
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(string(byteData))
    }
}


10.自定义类型和类别名

package main

import "fmt"

// 在go中, 自定义类型指的是使用type关键字定义的新类型, 它可以是基本类型的别名, 也可以是结构体, 函数等组合而成的新类型.
// 自定义类型可以帮助我们更好的抽象和封装数据, 让代码更加易读, 易懂, 易维护
type Code int      //自定义类型 类型定义
type MyCode = Code //类型别名, 类型名字打印类型时, 输出原始类型

// 类型别名不能绑定方法, 打印类型时是原始类型, 和原始类型比较, 类型不能转换
const (
    SuccessCode    Code = 0
    NetErrorCode   Code = 1
    OtherErrorCode Code = 2
)

// 相当于code对象了
func (code Code) getMsgCode() string {
    switch code {
    case SuccessCode:
        return "success"
    case NetErrorCode:
        return "net error"
    case OtherErrorCode:
        return "other error"
    }
    return "unknow code"
}
func (code Code) OK() (Code, string) {
    return code, code.getMsgCode()
}

func (code MyCode) Test() {
    fmt.Println(code.getMsgCode())
}

func webServer(name string) (code Code, msg string) {
    fmt.Println("Web Server:", name)
    switch name {
    case "animal":
        return SuccessCode.OK()
    case "animal2":
        return NetErrorCode.OK()
    case "animal3":
        return OtherErrorCode.OK()
    }
    return OtherErrorCode.OK()
}

func main() {
    myCode := new(MyCode)
    myCode.OK()
    fmt.Printf("myCode: %v, %T\n", myCode, myCode)
    var a Code = 1
    var b MyCode = 1
    if a == b {
        fmt.Println("a==b")
    } else {
        fmt.Println("a!=b")
    }
}


11.接口

package main

import "fmt"

// 接口是一组权包含方法名, 参数, 返回的未具体实现的方法集合
// 接口默认是值传递
type SingInterface interface {
    Sing()
}

// 空接口可以接受任何类型, 任何类型都实现了空接口
type EmptyInterface interface{}
type Chicken struct {
    Name string
}

type Dog struct {
    Name string
}

func (chicken Chicken) Sing() {
    fmt.Println(chicken.Name, " is sing")
}

func (dog *Dog) Sing() {
    fmt.Println(dog.Name, " is sing")
}

func sing(singInterface SingInterface) {
    //接口断言, xx.(type)
    ch, OK := singInterface.(Chicken)
    if OK {
        fmt.Println("是chicken", ch)
    } else {
        fmt.Println("不是chicken")
    }
    singInterface.Sing()

    switch singInterface.(type) {
    case Chicken:
        fmt.Println("Chicken")
    case *Dog:
        fmt.Println("*Dog")
    default:
        fmt.Println("未知")
    }
}

func Print(empty EmptyInterface) {
    fmt.Println(empty)
}

// any = interface{}
func Print2(empty interface{}) {
    fmt.Println(empty)
}

func main() {
    c := Chicken{"Chicken"}
    d := Dog{"Dog"}

    sing(c)
    sing(&d)

    Print2(d)
}