Golang基础5-指针、结构体、方法、接口

指针

和c/c++类似,但是go语言中指针不能进行偏移和运算,安全指针

&(取地址) *(根据地址取值)

nil(空指针)

make和new之前对比:make用于初始化slice,map,channel这样的引用类型

而new用于类型的内存分配,分配的值为类型0值,返回该类型指针

结构体

值传递

没有继承,但是可以通过组合来支持面向对象特性。

结构体中可以包括结构体,但是不能包括本身

简单demo

package main

import "fmt"

type person struct {
    name string
    city string
    age  int8
}

func main() {
    //创建变量
    var p1 person
    p1.name = "pprof.cn"
    p1.city = "北京"
    p1.age = 18
    fmt.Printf("p1=%v\n", p1)  //p1={pprof.cn 北京 18}
    fmt.Printf("p1=%#v\n", p1) //p1=main.person{name:"pprof.cn", city:"北京", age:18}

    var p2 = new(person)
    p2.name = "小明"
    p2.city = "武汉"
    p2.age = 10
    fmt.Printf("p2=%v\n", p2)
    fmt.Printf("p2=%#v\n", p2)

    //匿名结构体
    var user struct {
        Name string
        Age  int
    }
    //user := struct{
    //    Name string
    //    Age  int
    //}
    user.Name = "pprof.cn"
    user.Age = 18
    fmt.Printf("%#v\n", user)
}

注意可见性,如果变量名首字母大写,在其他包可以访问(类似于public),否则只能在相同package中访问。

结构体的嵌套

对于Student中匿名嵌套的话,输出对应值,不需要s.p

package main

import "fmt"

type Person struct {
    name string
    age  int
}

// Student 结构体嵌套和匿名嵌套
type Student struct {
    p      Person
    school string
    score  int
}

func main() {
    s := Student{
        p:      Person{name: "张三", age: 18},
        school: "武汉大学",
        score:  100,
    }

    fmt.Println(s.p.name)
}

方法

    • 绑定对象实例,只能为当前包内命名类型定义方法

方法定义:

   func (recevier type) methodName(参数列表)(返回值列表){}

    参数和返回值可以省略
    • 参数recevier任意命名,若方法未曾使用可省略参数名
    • receive可以是T和*T类型。T不能是接口
    • 不支持方法重载
    • 可以使用value或pointer调用全部方法,编译器自动转换

简单demo

receive的类型T和*T之间对比

package main

import "fmt"

// 结构体
type User struct {
    Name  string
    Email string
}

// 假设T,产生副本不影响原变量
func (u User) Notify() {
    fmt.Printf("&u = %p\n", &u)
    fmt.Println("User 通知消息给", u.Name, " 邮箱为:", u.Email)
    u.Email = "Notify"
}

//如果是*T,传入指针,就会影响u1
//func (u *User) Notify() {
//    fmt.Printf("u = %p\n", u)
//    fmt.Println("User 通知消息给", u.Name, " 邮箱为:", u.Email)
//    u.Email = "Notify"
//}

func main() {
    u1 := User{"user1", "user1.com"}
    fmt.Printf("&u1 = %p\n", &u1)
    u1.Notify()
    //u2 := &u1
    fmt.Println(u1) //不影响u1变量
    fmt.Println("*********")
    u2 := &User{"user2", "user2.com"}
    fmt.Printf("u2 = %p\n", u2)

    u2.Notify()
    fmt.Println(u2)

}

func (u User) Notify() 方法时输出,传递副本因此地址不同,修改u不影响mian函数的对象值

func(u *User)Notify()传递指针,影响对象变量的值。

总结:方法就是与特定类型关联的函数,方便相当于c++当中class中的成员函数。

匿名字段demo

通过组合实现于override继承之后覆盖方法的效果。

// 结构体
type User struct {
    Name  string
    Email string
}

type Manager struct {
    User
    Stage string
}

// User的方法
func (u *User) ToString() string {
    return fmt.Sprintf("%s %s\n", u.Name, u.Email)
}

// Manager的方法
func (m *Manager) ToString() string {
    return fmt.Sprintf("%s %s %s\n", m.Name, m.Email, m.Stage)
}

func main() {
    m := Manager{User: User{"李四", "manage.cn"}, Stage: "经理"}
    fmt.Println(m.ToString())
    fmt.Println(m.User.ToString())
}

接口

参考链接:https://www.cnblogs.com/chenny7/p/4497969.html

go语言接口详解:Go 语言接口的原理 | Go 语言设计与实现

interface抽象类型,是一组method的集合,类似于c++中的纯虚函数,如果一个类/对实现了interface中的所有方法就实现了interface接口。通过interface也就是可以实现多态特性。

简单demo

package main

import "fmt"

type Human struct {
    name  string
    age   int
    phone string
}

type Student struct {
    Human  //匿名字段
    school string
    loan   float32
}

type Employee struct {
    Human   //匿名字段
    company string
    money   float32
}

// Human实现SayHi方法
func (h Human) SayHi() {
    fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
}

// Human实现Sing方法
func (h Human) Sing(lyrics string) {
    fmt.Println("La la la la...", lyrics)
}

// Employee重载Human的SayHi方法
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)
}

//func (s Student) SayHi() {
//    fmt.Printf("Hi, I am %s, I study in %s. Loan is %f\n", s.name,
//        s.school, s.loan)
//}
//func (s Student) Sing(lyrics string) {
//    fmt.Println("student Sing")
//}

// Interface Men被Human,Student和Employee实现
// 因为这三个类型都实现了这两个方法
type Men interface {
    SayHi()
    Sing(lyrics string)
}

func main() {
    mike := Student{Human{"Mike", 25, "222-222-XXX"}, "MIT", 0.0}
    paul := Student{Human{"Paul", 26, "111-222-XXX"}, "Harvard", 100}
    sam := Employee{Human{"Sam", 36, "444-222-XXX"}, "Golang Inc.", 1000}
    tom := Employee{Human{"Tom", 37, "222-444-XXX"}, "Things Ltd.", 5000}

    //定义Men类型的变量i
    var i Men

    //i能存储Student
    i = mike
    fmt.Println("This is Mike, a Student:")
    i.SayHi()
    i.Sing("November rain")

    //i也能存储Employee
    i = tom
    fmt.Println("This is tom, an Employee:")
    i.SayHi()
    i.Sing("Born to be wild")

    //定义了slice Men
    fmt.Println("Let's use a slice of Men and see what happens")
    x := make([]Men, 3)
    //这三个都是不同类型的元素,但是他们实现了interface同一个接口
    x[0], x[1], x[2] = paul, sam, mike

    for _, value := range x {
        value.SayHi()
    }
}

通过调用接口相当于实现了多态。

可以继续实现嵌入接口。

空接口demo

空interface(interface{})不包含任何的method

所有的类型都实现了空interface

空接口可以存储任意类型

空interface对于描述起不到任何的作用(因为它不包含任何的method),但是空interface在我们需要存储任意类型的数值的时候相当有用,因为它可以存储任意类型的数值。它有点类似于C语言的void*类型。

    // 定义a为空接口,作为函数参数,或者与slice,map等增强灵活性
    var a interface{}
    var i int = 5
    s := "Hello world"
    // a可以存储任意类型的数值
    a = i
    a = s

interface{}可断言类型

空接口断言demo

package main

import "fmt"

type Human struct {
    Name string
    Age  int
}

type Student struct {
    Human
    School string
}

// 作为函数形参
func Show(a interface{}) {
    fmt.Printf("type of:%T value:%v\n", a, a)
}

//判断当前类型
func JustifyType(i interface{}) {
    switch v := i.(type) {
    case string:
        fmt.Println("当前传入为string:", v)
    case int:
        fmt.Println("当前传入为int:", v)
    case Student:
        fmt.Println("当前为Student类型", v)
    default:
        fmt.Println("暂未预料")
    }
}

func main() {
    i := "hello"
    Show(i)
    JustifyType(i)

    j := 10
    Show(j)
    JustifyType(j)

    Show(123)
    JustifyType(123)

    h := Human{"Human", 123}
    Show(h)
    JustifyType(h)

    k := Student{}
    Show(k)
    JustifyType(k)

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/572425.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

热知识:更多团队采用3个及以上内部开发者平台

01 介绍 根据 Perforce Puppet 的一份新报告中,平台工程的采用已经在一些企业内看到了成效,78% 的受访者表示他们的组织拥有专门的平台团队至少三年了。 然而,这并不意味着这些组织只使用同一套工具。四分之三的调查参与者表示,他…

如何使用SOLIDWORKS添加装饰螺纹线规格

在我们的设计过程中,有很多的时候螺纹规格在机械设计手册上没有,而我们的SOLIDWORKS软件里面录制的都是符合标准的的螺纹,至于其他的特种或者超出的规格需要我们设计人员去手工添加,以下介绍我们装饰螺纹线新规格的添加方法&#…

关于PMO卓越中心职能建设的实践与思考︱PMO大会

全国PMO专业人士年度盛会 浪潮电子信息产业股份有限公司PMO时军先生受邀为PMO评论主办的2024第十三届中国PMO大会演讲嘉宾,演讲议题为“让组织持续卓越——关于PMO卓越中心职能建设的实践与思考”。大会将于5月25-26日在北京举办,敬请关注! …

菜单访问url/接口url为什么要带时间戳

一, 问题 1,菜单url中如果不加时间戳,会导致什么问题。我们现在做一个东西,需要获取菜单的访问地址,我们要拼这个地址 2,查询接口中,时间戳,如果不加,具体导致什么问题 二…

Vue集成three.js,加载glb、gltf类型的3d模型

安装基本依赖 // 注意OrbitControls要加{},注意路径是jsm import { OrbitControls } from ‘three/examples/jsm/controls/OrbitControls.js’; // import { dat } from ‘three/examples/jsm/controls/dat.gui.js’; // dat gui这个插件,是另外自己下载…

杰理使用USB声卡模式时关闭MIC

杰理在使用PC模式的时候,想只保留扬声器,但不要打开MIC功能,可以配置USB_DEVICE_CLASS_CONFIG中把MIC_CLASS去掉,然后重新编译就可以了。

Kimi 高效使用技巧,80%的人都不知道

关注我, AI 学习之旅上,我与您一同成长! 一、引言 Kimi 作为国产之光,在过去的一个多月里成为国内大模型的香饽饽。据数据分析,Kimi 网页、APP、小程序等各端的日活已经突破 300 万,超过文心一言、通义千问、智谱清言…

单链表实现通讯录

不过多赘述了 顺序表的增删查改-CSDN博客https://blog.csdn.net/bkmoo/article/details/137566495?spm1001.2014.3001.5502 使用顺序表实现通讯录-CSDN博客https://blog.csdn.net/bkmoo/article/details/137676561?spm1001.2014.3001.5502这里没有使用文件操作只是简单的使…

6.MMD ray渲染 材质的添加及打光方法

材质 前置准备 先准备好模型和场景 将ray控制器拖入进去 添加完默认的材质以后的效果 打开插入材质页面 打开MaterialMap栏 将流萤的模型展开 自发光 现在给领带添加一个自发光效果 在自发光Emissive里,打开x1,选择albedo,白光 现在…

使用微软Phi-3-mini模型快速创建生成式AI应用

微软Phi-3大语言模型是微软研究院推出的新一代系列先进的小语言模型。Phi-3系列包括phi-3-mini、phi-3-small和phi-3-medium三个不同规模的版本。这些模型在保持较小的参数规模的同时,通过精心设计的训练数据集和优化的算法,实现了与大型模型相媲美的语言…

【CVPR2023】Re:InterHand:一个用于3D交互手部姿态估计的重光照数据集

这篇论文的标题是《A Dataset of Relighted 3D Interacting Hands》,作者是Gyeongsik Moon, Shunsuke Saito, Weipeng Xu, Rohan Joshi, Julia Buffalini, Harley Bellan, Nicholas Rosen, Jesse Richardson, Mallorie Mize, Philippe de Bree, Tomas Simon, Bo Pen…

玩转PyCharm

玩转PyCharm PyCharm是由JetBrains公司开发的提供给Python专业的开发者的一个集成开发环境,它最大的优点是能够大大提升Python开发者的工作效率,为开发者集成了很多用起来非常顺手的功能,包括代码调试、高亮语法、代码跳转、智能提示、自动补…

MyBatis 核心配置讲解(上)

大家好,我是王有志,一个分享硬核 Java 技术的互金摸鱼侠。 前两篇的文章中我们分别介绍了 MyBatis 和 MyBaits 的应用组成,到这里基础篇的内容就结束了。 从今天开始,我们正式进入 MyBatis 学习的第二阶段:MyBatis 的…

【QT学习】9.绘图,三种贴图,贴图的转换,不规则贴图(透明泡泡),简单绘图工具制作

一。绘图的解释 Qt 中提供了强大的 2D 绘图系统,可以使用相同的 API 在屏幕和绘图设备上进行绘制,它主要基于QPainter、QPaintDevice 和 QPaintEngine 这三个类。 QPainter 用于执行绘图操作,其提供的 API 在 GUI 或 QImage、QOpenGLPaintDev…

maya blendshape

目录 shape编辑器 maya创建blendshape python 脚本 添加形变动画 查看顶点个数 shape编辑器 打开方式: 窗口-动画编辑器-形变编辑器 maya创建blendshape python 脚本 import maya.cmds as cmds# 创建基础网格 - 球体 baseMesh cmds.polySphere(name"bas…

Postman 工具发送请求的技巧与实践

在开发和测试 API 时,发送 JSON 格式的请求是一个常见需求。 在 Postman 中构建和发送 JSON 请求 创建一个新的请求 首先,在 Postman 启动界面上找到并点击 “New” 按钮,选择 “HTTP Request” 来开始新建一个请求。这一步骤允许你定义请…

Unity射击游戏开发教程:(7)Powerup的使用

确定 PowerUp 效果应持续多长时间 我在游戏中放置的第一个道具是三重射击。当玩家收集三重射击能量时,他们可以一次发射 3 束激光,而正常情况下只能发射 1 束激光。在实施道具时,您需要考虑它们的功能以及它将如何影响游戏玩法。至于三连射&

Linux-缓冲区(简单理解)

1. 缓冲区是什么 缓冲区就是一段内存空间。 2. 为什么要有缓冲区 IO写入有两种: 写透模式(WT) 成本高,效率低写回模式(WB) 成本低,效率高 写透模式:每次的文件写入都要立即刷新…

海外仓WMS管理系统:标准化海外仓管理模式,效率和管理模式双提升

就目前的跨境电商发展速度和体量来看,标准化海外仓管理的模式不再是一个选项,而是必走之路。 今天会重点和大家聊一下,海外仓企业应该如何利用好WMS管理系统,快速的标准化仓库管理的模式,以及大家比较关心的&#xff0…

JAVA读取文件完成词频统计

词频统计原数据和结果数据地址:https://download.csdn.net/download/LiHaoHang6/88845654?spm1001.2014.3001.5501 运行效果展示: 原数据展示: 词频统计思路: 1:先通过BufferedReader来读取本地文本文件,之后将文本…