【Go基础】结构体

news2024/9/20 12:35:24

1. 结构体引入

Golang也支持面向对象编程,但是和传统的面向对象有区别,并不是像Java、C++那样纯粹的面向对象语言,而是通过特别的手段实现面向对象特点。

Golang没有类(Class)的概念,但是提供了结构体(struct),和其他编程语言中的类(class)有同等地位,可以理解为 :Go基于struct"拐弯抹角"的实现了面向对象的特点。

Golang面向对象编程非常简洁,去掉了传统OOP语言的 方法重载、构造函数、和析构函数、this、super一系列东西,但是保留了封装、继承、多态的特性,只是和其他语言的实现方式不同。

2. 结构体的定义

使用 type​ 和 struct​定义一个结构体

type People struct {
}

People就成了一个结构体,当然可以为People添加一些字段

type People struct {
	name string
	age string
	addr string
}

定义之后如何声明呢 ?

有以下几种方式 :

  1. 使用 var 变量名 结构体类型

    var people People
    people.name = "小明"
    people.age = 18
    fmt.Println(people) 
    // {小明 18}
    
  2. 变量名 := new(结构体类型)

    new返回的指向特定类型的指针,所以这种方式返回的是 指向一个People结构体 的指针

    people := new(People)
    people.name = "小明"
    people.age = 18
    fmt.Println(people) 
    // &{小明 18}
    

    为什么people是指针,还能使用 .​ 来访问结构体中的变量呢?使用 (*people).name 、(*people).age​当然可以访问,只是这种不好写,Go为我们进行了优化。

    如果第一种方式和这种方式让你选一种,你用哪一个呢?当一个结构体中的字段特别多时,直接创建该结构体会占用大量空间,但是指针不一样,指针固定大小。所以以上两种第二种常用。不过还有其他方式。

  3. 变量名 := 结构体类型{字段1:值, 字段1:值,}

    使用这种方式跟第一种差不多,都是直接开辟空间,不过这种方式可以直接对属性赋值

    (左边用var​还是:=​都一样)

    people := People{
    	name: "小明",
    	age: 18,
    }
    fmt.Printf("people的类型为: %T\n", people)
    // main.People
    
    // 这样也一样
    var people1 People = People{
    	name: "小明",
    	age: 18,
    }
    

    这可不是json,字段名不加双引号,最后一个字段后要要加逗号。

  4. 变量名 := &结构体类型{字段1:值, 字段2:值,}

    这种方式和第二种像,返回的是一个指向结构体的指针。

    people := &People {
    	name: "小明",
    	age: 18,
    }
    fmt.Printf("people的类型为: %T\n", people)
    //  *main.People
    

这四种方式选择哪一种,这要看习惯与需求,熟练用其中一种,可以看懂其他的方式就行。

初始化时可以直接列出全部的字段值,这种方式的缺点是 :无法指定字段,且一次性需要给全部字段赋值,如果后续由增加或删除,会出问题。

type People struct {
	name string
	age int
}
func main() {
	people := &People {
		"小明",
		18,
	}
}

匿名字段 :没有名字的字段。

type People struct {
	string
	int
}
func main() {
	people := &People {
		"小明",
		18
	}

}

赋值时需要严格按照字段类型与顺序,一般不用匿名字段,因为可读性太差,且如果出现多个string int类型,可读性更差

3. 结构体之间的转换

当两个不同类型的结构体中,字段数量字段名字段顺序字段类型全部相同时,这两个字段可以相互转换。

type People struct {
	name   string
	age    int
	height float32
}

type Monkey struct {
	name   string
	age    int
	height float32
}

func main() {
	// 声明一个People类型的结构体
	people := &People{
		name:   "小明",
		age:    18,
		height: 180.4,
	}
	// 将上述结构体变量转换为 *Monkey 类型
	monkey := (*Monkey)(people)
	fmt.Println(monkey)
	// 打印结果:  &{小明 18 180.4}

}

两个结构体是否能相互转换 :

字段数、字段名、字段顺序、字段类型​ 全部相同,缺一个就无法编译。

4. 结构体嵌套

说人话,结构体里还有结构体。

type Address struct {
	province string
	city     string
}
type People struct {
	id      int
	name    string
	age     int
	address Address
}
func main() {
	people := &People{
		id:   1,
		name: "小明",
		age:  18,
		address: Address{
			province: "河北",
			city:     "衡水",
		},
	}
	fmt.Println(people)
}

需要注意的是,People中的address字段如果是指针,在赋初值时就申请指针,是结构体就直接赋值结构体。

可以直接people.address.city访问嵌套结构体中的值.

fmt.Println(people.address.city)

这个经常使用,因为仅仅使用一个结构体无法描述出一个复杂的类型,就可以分为多个字段。

结构体中也可以有结构体数组,不过很少用这种方式一个一个new,都是从前端传来的json直接转换。

package main

import (
	"fmt"
	"strconv"
)

type Phone struct {
	name  string
	price int
}

func NewPhone(name string, price int) Phone {
	return Phone{
		name:  name,
		price: price,
	}
}

type People struct {
	name   string
	phones []Phone
}

func NewPeople(name string, phones []Phone) People {
	return People{
		name:   name,
		phones: phones,
	}
}

func main() {
	// 创建一个People数组
	people := NewPeople("小明", make([]Phone, 5, 200))
	// 循环给people数组中的值赋值
	for i := 0; i < 5; i++ {
		phoneName := "小米" + strconv.Itoa(i)
		phone := NewPhone(phoneName, 1000*(i+1))
		//
		people.phones[i] = phone
		// 如果在初始化切片时指定长度为0或者小于5,使用append()扩容
		// people.phones = append(people.phones, phone)
	}
	fmt.Println(people)

}

5. 方法的引入

方法是作用在指定的数据类型上、和指定的数据类型绑定,因此自定义类型都可以有方法,通常给结构体定义一些方法,以便外部调用,就像Java中的setter/getter方法、C++中的构造函数、析构函数一样。当然,Go语言中的方法并没有放在结构体中,而是和结构体分离。

形式:

func (变量名 : 自定义类型) 方法名(参数列表) (返回值列表) {

// 方法体

}

第一个括号中的变量不需要传入,而是==“谁调用,这个变量就是谁”==

当然可以不使用第一个变量。

给People定义一个初始化方法:

type People struct {
	name string
	age int
}
func newPeople(name string, age int) (*People) {
	return &People {
		people.name = name
		people.age = age
	}
}
func main() {
	people := newPeople("小明", 18)
}

这个newPeople方法接收两个变量,name和age,通过这两个变量创造一个Person对象并返回,以后再也不用频繁的写初始化方法了。

以下是使用第一个变量的例子 :

func (people *People) SetAge(age int) {
	people.age = age
}

这个方法的调用者必须是People类型的指针,否则会报错。

people := newPeople("小明", 18)
fmt.Println(people) // &{小明 18}
people.SetAge(10)
fmt.Println(people.age) // 10

就是方法的特殊性,让我们可以对结构体进行各种操作。你可以单独定义一个文件,在这个文件中完成对结构体的封装。

image

方法和函数的区别 :

  • 方法被调用者影响。
  • 函数与没有具体的调用者。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Nacos的学习

Nacos的学习 1、下载地址 https://github.com/alibaba/nacos/releases/tag/2.1.1 在bin目录中输入命令 startup.cmd -m standalone 输入localhost:8848/nacos 账号&#xff1a;nacos&#xff0c;密码&#xff1a;nacos 2、Spring与Nacos &#xff08;1&#xff09;新增一个配…

100天精通Python(数据分析篇)——第72天:Pandas文本数据处理方法之判断类型、去除空白字符、拆分和连接

文章目录每篇前言一、Python字符串内置方法1. 判断类型2. 去除空白字符3. 拆分和连接二、Pandas判断类型1. str.isspace()2. str.isalnum()3. str.isalpha()4. str.isdecimal()5. str.isdigit()6. str.isnumeric()7. str.istitle()8. str.islower()9. str.isupper()三、Pandas去…

音视频技术开发周刊 | 279

每周一期&#xff0c;纵览音视频技术领域的干货。新闻投稿&#xff1a;contributelivevideostack.com。基于NeRF的APP上架苹果商店&#xff01;照片转3D只需一部手机这个名叫Luma AI的“NeRF APP”&#xff0c;正式上架App Store后爆火。反 AiArt 运动中两件匪夷所思的蠢事Redd…

Elastic:使用 Postman 来访问

Elastic&#xff1a;使用 Postman 来访问 学习资料 Elastic&#xff1a;使用 Postman 来访问 Elastic Stack 当我们配置好elasticsearch的SSL之后&#xff0c;我们用网页https访问&#xff0c;输入账户及密码之后&#xff0c;可以成功访问数据。 但是用postman时&#xff0c;我…

2023/1/15 JS-闭包问题研究

1 举个栗子分析执行上下文 1: let a 3 2: function addTwo(x) { 3: let ret x 2 4: return ret 5: } 6: let b addTwo(a) 7: console.log(b)为了理解 JavaScript 引擎是如何工作的&#xff0c;让我们详细分析一下&#xff1a; 在第 1 行&#xff0c;我们在全局执行上…

Linux chattr命令

Linux chattr命令Linux 命令大全Linux chattr命令用于改变文件属性。这项指令可改变存放在ext2文件系统上的文件或目录属性&#xff0c;这些属性共有以下8种模式&#xff1a;a&#xff1a;让文件或目录仅供附加用途。b&#xff1a;不更新文件或目录的最后存取时间。c&#xff1…

从上到下看内存

从上到下看内存 1. 本篇目录 内存条,总线,DMAC 内存管理内存分类 内存相关的系统调用 java中的内存 2. 内存条,总线,DMAC 内存条 内存条&#xff1a;内存条其实是非常常见的一个组件。内存条是插在主板上的。 总线 内存条插好以后&#xff0c;计算机之间要进行交互。…

Linux 中断子系统(四):GIC中断初始化

以我手中的 imx6ull开发板为例。 如果使用设备树的话就需要在设备树中设置好中断属性信息,Linux 内核通过读取设备树中的中断属性信息来配置中断。对于中断控制器而言,设备树绑定信息参考文档 Documentation/devicetree/bindings/arm/gic.txt。 打开 imx6ull.dtsi 文件,其…

UDS诊断系列介绍12-11服务

本文框架1. 系列介绍1.1 11服务概述2. 11服务请求与应答2.1 11服务请求2.2 11服务正响应2.3 11服务否定响应3. Autosar系列文章快速链接1. 系列介绍 UDS&#xff08;Unified Diagnostic Services&#xff09;协议&#xff0c;即统一的诊断服务&#xff0c;是面向整车所有ECU的…

三种方法解决React类组件中this指向问题

从onClick事件不加括号说起 import React from react import ./App.css class TestComponent extends React.Component {clickHandler () {console.log(111)console.log(this指向&#xff1a;, this)}render () {return (<button onClick{this.clickHandler()}>点击我&l…

机器学习实战4:基于马尔科夫随机场的图像分割(附Python代码)

目录0 写在前面1 图像分割问题2 图像像素邻域3 观测场与标记场4 马尔科夫随机场建模5 Python实现5.1 计算能量函数5.2 退火优化5.3 效果展示0 写在前面 机器学习强基计划聚焦深度和广度&#xff0c;加深对机器学习模型的理解与应用。“深”在详细推导算法模型背后的数学原理&a…

分享6个对象数组去重的方法

大家好&#xff0c;关于对象数组去重的业务场景&#xff0c;想必大家都遇到过类似的需求吧&#xff0c;针对这样的需求&#xff0c;你是怎么做的呢。下面我就先和大家讨论下基于对象的某个属性如何去重。方法一&#xff1a;使用 .filter() 和 .findIndex() 相结合的方法使用 fi…

基于AD Event日志监测AdminSDHolder

01、简介 AdminSDHolder是一个特殊的AD容器&#xff0c;通常作为某些特权组成员的对象的安全模板。Active Directory将采用AdminSDHolder对象的ACL并定期将其应用于所有受保护的AD账户和组&#xff0c;以防止意外和无意的修改并确保对这些对象的访问是安全的。如果攻击者能完全…

## Leetcode刷题Day24-------------------回溯算法

Leetcode刷题Day24-------------------回溯算法 1. 理论基础 题目链接/文章讲解&#xff1a;https://programmercarl.com/%E5%9B%9E%E6%BA%AF%E7%AE%97%E6%B3%95%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html视频讲解&#xff1a;https://www.bilibili.com/video/BV1cy4y167mM …

Linux文件目录与路径、内容查找命令及文件颜色知识总结

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;Java案例分…

SpringBoot 整合Shiro实现动态权限加载更新+Session共享+单点登录

一.说明 Shiro是一个安全框架,项目中主要用它做认证,授权,加密,以及用户的会话管理,虽然Shiro没有SpringSecurity功能更丰富,但是它轻量,简单,在项目中通常业务需求Shiro也都能胜任. 二.项目环境 MyBatis-Plus版本: 3.1.0 SpringBoot版本:2.1.5 JDK版本:1.8 Shiro版本:1.4…

ASUS X415安装系统找不到硬盘解决办法

同事让我帮忙安装系统&#xff0c;笔记本电脑型号是ASUS X415。原本以为是手到擒来的事情&#xff0c;结果我在上面还是消耗了不少时间。 现象 老毛桃PE 无法识别到硬盘。微PE可以识别到硬盘&#xff0c;但是系统安装以后&#xff0c;无法正常启动。启动出现蓝屏。或者无限等…

codewars闯关玩耍1

codewars闯关玩耍1 codewars网址&#xff1a;https://www.codewars.com/dashboard 大一时在知乎上看到的网站&#xff0c;然后 点击、收藏、吃灰 一键三连&#xff0c;最近翻收藏夹的时候突然又看见了决定进来玩玩&#xff0c;练练英语&#xff0c;巩固下python 以后此系列&a…

javaweb10 JSP语法、JSTL、EL表达式、JSP标签、九大内置对象

文章目录一、JSP简介二、JSP原理三、JSP语法四、JSP指令五、九大内置对象六、EL表达式七、JSP标签八、JSTL标签一、JSP简介 JSP&#xff08;java sever pages&#xff09;&#xff1a;java服务器端页面&#xff0c;和servlet一样&#xff0c;用于动态web技术 写JSP就像在写HTM…