当前位置: 首页 > article >正文

golang-struct结构体

struct结构体

概述

Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。

结构体是 Golang 中一种复合类型,它是由一组具有相同或不同类型的数据字段组成的数据结构。

结构体是一种用户自定义类型,它可以被用来封装多个字段,从而实现数据的组合和抽象化。

在 Golang 中,结构体是一种非常灵活和扩展性强的类型,它支持嵌套、组合、方法等高级特性。

类比

Golang的结构体和其他高级语言中的类相似,

1.结构体字段就是类的变量或属性。
2.结构体方法就是类的方法。
3.结构体的嵌套就是类的继承。
4.结构体的组合可以实现类的多态。

结构体的概念和定义

基本语法

结构体定义需要使用 type 和 struct 语句。

struct 语句定义一个新的数据类型,结构体中有一个或多个成员。

type 语句设定了结构体的名称。结构体的格式如下:

//语法结构
type struct_variable_type struct {member definitionmember definition...member definition
}//中文
type 结构体类型名 struct{成员1  成员类型成员2  成员类型成员3  成员类型...
}

举例

type Person struct{name stringage int64
}

注意

type表明结构体本质上就是一个类型,类型名为Person。

结构体字段

结构体的字段可以是任意类型,甚至是结构体本身,也可以是函数或者接口。

如果一个字段在代码中从来不会被用到,那可以把它命名为_,即空标识符。

大小写问题

结构体中的字段通过首字母大小写来控制私有或公有。

私有属性或方法只能在本包内访问。
公有属性或方法可以跨包访问。

json标签映射不能访问小写开头的字段是因为标签映射需要借助reflect包,属于跨包访问。

字段标记举例

type Person struct {Name  string `json:"name"`Age     int   `json:"age"`Email string `json:"email"`
}

这些标记信息通过反射接口可见,并参与结构体的类型标识,但在其他情况下被忽略。

结构体实例化

字面量初始化

字面量初始化时实例的声明和初始化同时进行。

基本语法

var 变量名 结构体类型 = 结构体类型{字段1:,字段2:,
}//简易初始化
var 变量名 = 结构体类型{字段1:,字段2:,
}//极简初始化
变量名 := 结构体类型{字段1:,字段2:,
}

举例

package struct_knowledgeimport "fmt"func CreateStruct(){type Person struct{name string age int64}var person = Person{name:"张三",}fmt.Printf("person实例的值为%#v\n",person)
}

结果

person实例的值为struct_knowledge.Person{name:"张三", age:0}

小结

1.实例的最后一定要用,结尾

var person = Person{//实例的最后一定要用,结尾name:"张三",
}

2.声明却没赋值的属性会采用零值

var person = Person{//实例的最后一定要用,结尾name:"张三",//age没有赋值
}//结果:
person实例的值为struct_knowledge.Person{name:"张三", //采用零值age:0,
}

赋值实例化

访问结构体成员

如果要访问结构体成员(属性和方法),需要使用点号.操作符,格式为:

结构体实例.成员名

注意是结构体实例

举例

package struct_knowledgeimport "fmt"func CreateStruct(){type Person struct{name string age int64}var person = Person{name:"张三",}fmt.Printf("person实例的值为%#v\n",person)//访问成员fmt.Printf("person的name值为%#v\n",person.name)
}

结果

person实例的值为struct_knowledge.Person{name:"张三", age:0}
person的name值为"张三"

注意

结构体实例可以访问成员属性和成员变量,结构体类型名是不行的。(结构体类型名就是一个类型)

赋值初始化

基本语法

var 实例名 结构体类型
实例.属性 = 值
实例.属性2 =

举例

package struct_knowledgeimport "fmt"func CreateStruct2(){type Person struct{name string age int64}var person Personfmt.Printf("未赋值前,结构体实例的值为%#v\n",person)person.name = "张三"person.age = 19fmt.Printf("赋值后,结构体实例的值为%#v\n",person)
}

结果

未赋值前,结构体实例的值为struct_knowledge.Person{name:"", age:0}
赋值后,结构体实例的值为struct_knowledge.Person{name:"张三", age:19}

小结

1.结构体实例未赋值时,所有字段采用零值。

顺序初始化

我们也可以不写属性名赋值,但是这种必须要保证赋值顺序和结构体声明顺序一致。

顺序初始化时,实例的声明和赋值同时进行,且赋值要与结构体字段一一对应。

package struct_knowledge
import "fmt"
func CreateStruct3(){type Person struct{name string_ boolage int64}var person =  Person{"张三",true,19}fmt.Printf("赋值后,结构体实例的值为%#v\n",person)
}

结果

赋值后,结构体实例的值为struct_knowledge.Person{name:"张三", _:false, age:19}

注意事项

1.结构体中即使是`_`这种表示空标识的字段,在顺序初始化时也得赋值。
2.赋值时值的个数要与字段个数相同,不能多也不能少。

阶段总结

字面量初始化、赋值初始化都可以看作关键字赋值,无需考虑顺序,没有赋值的采用零值。

顺序初始化则是位置赋值,需要与结构体的字段一一对应,赋值个数即不能多,也不能少。

new函数

基本语法

new 函数是 Golang 中的一个内置函数,它用于创建一个指向新分配的类型为T的零值的指针。

在使用 new 函数时,我们需要传递一个类型参数,该参数表示要分配内存的类型。

基本语法

var 结构体实例 = new(结构体类型)

举例

package struct_knowledgeimport "fmt"func CreateStructByNew() {type Person struct{name stringage int}//new函数实例化person := new(Person)fmt.Printf("person的类型为%T\n",person)person.name = "张三"person.age = 19fmt.Printf("赋值后,结构体实例person的值为%#v\n",person)//普通实例var person1 Personfmt.Printf("person的类型为%T\n",person1) }

结果

person的类型为*struct_knowledge.Person
赋值后,结构体实例person的值为&struct_knowledge.Person{name:"张三", age:19}
person的类型为struct_knowledge.Person

小结

new函数得到的实例是结构体指针类型,但是由于golang的结构体和数组二者的引用类型赋值时不需要使用*指针类型取值,所以很容易产生混淆。

new的等价

new函数其实进行了两步操作

1.声明了一个指针变量
2.分配内存

我们也可以自行声明指针变量,然后用new分配内存。

声明指针变量

func CreateStruct7(){type Person struct{name stringage int}/*只声明了变量,没有分配内存,值为nil*/var person1 *Personfmt.Printf("未分配内存前,person1的值为%#v\n",person1)//未分配内存前为nil,不能操作//panic: runtime error: invalid memory address or nil pointer dereference// person1.age = 19
}

结果

未分配内存前,person1的值为(*struct_knowledge.Person)(nil)

此时我们不能赋值,就和空切片、空map一样,我们还需要分配内存。给指针类型分配内存就需要使用

//得到一个该类型的指针,并且分配了空间
new(类型)

分配空间后,将采用结构体字段的零值。

分配空间举例

package struct_knowledgeimport "fmt"func CreateStruct7(){type Person struct{name stringage int}/*只声明了变量,没有分配内存,值为nil*/var person1 *Personfmt.Printf("未分配内存前,person1的值为%#v\n",person1)//panic: runtime error: invalid memory address or nil pointer dereference// person1.age = 19//分配空间person1 = new(Person)fmt.Printf("分配内存后,未赋值前,person1的值为%#v\n",person1)person1.name = "张三"fmt.Printf("分配内存并且赋值后,person1的值为%#v\n",person1)
}

结果

未分配内存前,person1的值为(*struct_knowledge.Person)(nil)
分配内存后,未赋值前,person1的值为&struct_knowledge.Person{name:"", age:0}
分配内存并且赋值后,person1的值为&struct_knowledge.Person{name:"张三", age:0}
new的字面量赋值

易混淆误区

我们声明了一个指针类型的结构体,我们可以给他直接赋值,例如

type Person struct{name stringage int
}
var person = new(Person)
//直接赋值
person.name = "张三"

实际上这是因为golang对结构体和数组做了处理,再给结构体和数组的指针类型直接赋值时不需要使用*指针类型取内容。

var price = new(int)
//price是*int类型,在修改时为
*price = 15var lisa = new(Person)
//lisa的类型实际上为 *Person
/*常规操作*lisa.name = "张三"但是golang决定这样可读性太差就去掉了前面的*,反而增加了我们理解的难度
*/
lisa.name = "张三"

指针类型赋值

由于new函数得到的是指针类型,所以字面量赋值时就需要。

type Person struct{name stringage int
}
var person = new(Person)//需要&取地址获得指针类型
person = &Person{name:"张三",age:19
}

小结

由于结构体是值类型,所以我们在使用时要严格区分传递的是否是指针,不要囫囵吞枣。

结构体字段

golang的结构体字段很复杂,值得单独讲解。

基本形式

基本语法

字段名和字段类型

type 结构体名 struct{字段1 字段类型字段2 字段类型...
}

结构体的首字母小写,则该结构体类型只能在本包访问,反之可以跨包访问。

结构体字段的首字母小写,则该结构体字段只能在本包访问,反之可以跨包访问。

举例

type Person struct{//该字段可以跨包访问Name string//该字段不能跨包访问age int
}

跨包访问

package1//在包1中通过包2访问就叫跨包访问2.变量

同类型省略形式

基本语法

type 结构体类型 struct{字段1 类型A字段2,字段3 类型B字段4 类型C
}

等价于

type 结构体类型 struct{字段1 类型A字段2 类型B字段3 类型B字段4 类型C
}

举例

package struct_knowledgeimport "fmt"func CreateStruct4(){//同类型字段简写type Struct1 struct{IsOk boolage,price intname string}var Struct1Item = Struct1{true,20,25,"张三"}fmt.Printf("赋值后,结构体实例的值为%#v\n",Struct1Item)
}

结果

赋值后,结构体实例的值为struct_knowledge.Struct1{IsOk:true, age:20, price:25, name:"张三"}

省略字段名

基本语法

这种省略字段名实际上就是拿类型作为字段名。

类型名虽然是关键字,但是在结构体中允许关键字当字段名。

这是为结构体嵌套做铺垫。

因为嵌套结构体就是将其他结构体类型直接写到该结构体中。

type 结构体类型 struct{字段1 类型A类型B字段1 类型C
}

等价于

type 结构体类型 struct{字段1 类型A字段B 类型B字段1 类型C
}

举例

package struct_knowledgeimport "fmt"func CreateStruct5(){//省略字段名type Struct2 struct{name stringstringboolage int}//相当于/*type Struct2 struct{name stringstring stringbool  boolage int}*/var Struct2Item Struct2Struct2Item.name = "张三"Struct2Item.bool = truefmt.Printf("赋值后,结构体实例的值为%#v\n",Struct2Item)
}

结果

赋值后,结构体实例的值为struct_knowledge.Struct2{name:"张三", string:"", bool:true, age:0}

同名字段

在同一个结构体中声明同名字段,会报错,例如

//报错:name redeclared
type Struct1 struct{name stringname string
}

注意

由于golang严格区分大小写,所以首字母大小写不同或者个别字母大小写不同属于不同字段,例如

//正确,属于不同字段
type Struct1 struct{name stringName string
}

字段冲突

之所以会考虑到这个问题,是因为后续结构体嵌套会遇到同名字段问题。

结构体指针

常见方法

常见的获取结构体指针的方式如下:

package struct_knowledgeimport "fmt"
//获得指针类型结构体实例的方式
func CreateStruct8(){type Person struct{name stringage int}/*方式1:声明指针类型变量,然后用new分配内存*/var person1 *Personperson1 = new(Person)fmt.Printf("分配内存后,未赋值前,person1的值为%#v\n",person1)/*方式2:声明指针类型变量,然后字面量赋值分配内存*/var person2 *Personperson2 = &Person{}fmt.Printf("分配内存后,未赋值前,person2的值为%#v\n",person2)/*方式3:直接用new函数声明指针类型并分配内存*/var person3 = new(Person)fmt.Printf("分配内存后,未赋值前,person3的值为%#v\n",person3)/*方式4:直接用字面量取地址*/var person4 = &Person{}fmt.Printf("分配内存后,未赋值前,person4的值为%#v\n",person4)
}

结果

分配内存后,未赋值前,person1的值为&struct_knowledge.Person{name:"", age:0}
分配内存后,未赋值前,person2的值为&struct_knowledge.Person{name:"", age:0}
分配内存后,未赋值前,person3的值为&struct_knowledge.Person{name:"", age:0}
分配内存后,未赋值前,person4的值为&struct_knowledge.Person{name:"", age:0}

有个方法可以分辨操作的是否是指针,就是打印时前面是否带&

构造函数法

所谓构造函数法,就是自定义一个函数,返回结构体指针类型,该方法的命名规范New+结构体类型名,例如

 func NewPerson(name string, age int) *Person {return &Person{Name: name, Age: age}}p := NewPerson("Tom", 25)

实际上就是字面量赋值指针类型。

结构体传参

结构体实例为值类型

由于结构体是值类型,所以直接传递结构体实例时,在函数内部操作该实例的拷贝对外部原实例没影响。

package struct_knowledgeimport "fmt"//注意需要在包外操作的字段一定要首字母大写
//私有字段无法跨包访问,会提示undefined
type Student struct{Name stringAge int
}//结构体是值类型
func StructByVal(st Student){st.Age = 20fmt.Printf("函数内该结构体实例的值为%#v\n",st)
}

调用

package mainimport ("fmt""go_learn/struct_knowledge"
)//这是入口文件
func main(){//验证结构体是值类型var myStudent struct_knowledge.StudentmyStudent.Name = "张三"struct_knowledge.StructByVal(myStudent)fmt.Printf("函数外该结构体实例的值为%#v\n",myStudent)
}

结果

函数内该结构体实例的值为struct_knowledge.Student{Name:"张三", Age:20}
函数外该结构体实例的值为struct_knowledge.Student{Name:"张三", Age:0}

由于结构体是值类型,所以函数内的操作无法影响到外面的原始实例。

这也解释了为什么前后端交互传递的都是结构体实例指针,因为需要得到前端传递的值。

使用指针类型传参

举例

package struct_knowledgeimport "fmt"type Student struct{Name stringAge int
}//指针类型传递送
func StructByPoint(st *Student){//golang的数组与结构体不需要显式取内容st.Name = "里萨"st.Age = 25fmt.Printf("函数内该结构体实例的值为%#v\n",st)
}

调用

package mainimport ("fmt""go_learn/struct_knowledge"
)//这是入口文件
func main(){//指针类型传值var myStudent= new(struct_knowledge.Student)myStudent.Name = "张三"struct_knowledge.StructByPoint(myStudent)fmt.Printf("函数外该结构体实例的值为%#v\n",myStudent)
}

结果

函数内该结构体实例的值为&struct_knowledge.Student{Name:"里萨", Age:25}
函数外该结构体实例的值为&struct_knowledge.Student{Name:"里萨", Age:25}

传递结构体实例的指针可以修改外部实例。

注意事项

需要我们给结构体指针赋值时不需要使用*取结构体内容,例如

type Student struct{Name stringAge int
}
var student = new(Student)
student.Name = "张三"

但是他还是结构体指针类型,当我们需要传参时,如果参数要求的是值不是指针,那我们仍然需要*取结构体内容。

type Student struct{Name stringAge int
}
var MyStudent = new(Student)
MyStudent.Name = "张三"func Add(st Student){...
}//由于函数参数要结构体的值,所以需要结构体指针取值
Add(*MyStudent)

相应的如果函数要的是指针,我们就要传递指针,例如

type Student struct{Name stringAge int
}
//这里是值类型
var MyStudent Student
MyStudent.Name = "张三"//函数参数要求指针
func Add(st *Student){...
}//传递指针类型
Add(&MyStudent)

相关文章:

golang-struct结构体

struct结构体 概述 Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。 结构体是 Golang 中一种复合类型,它是由一组具有相同或不同类型的数据字段组成的数据结构。 结构体是一种用户自定义类型,它可…...

深入理解事务

在数据库管理中,事务是一个至关重要的概念。无论是金融交易、库存管理还是用户数据更新,事务都确保了数据的完整性和一致性。本文将详细介绍为什么需要事务、什么是事务、事务的四大特征、如何在MySQL中使用事务以及MyBatis对事务的配置。 一、为什么需…...

基于SpringBoot + Vue 的药店药品信息管理系统

基于SpringBootVue的药品药店药房信息系统(带文档) 角色: 用户,管理员,员工 功能: 管理员: 首页、个人中心、用户管理、员工管理、药品类别管理、药品信息管理、药品入库管理、药品出库管理、在线咨询管理、留言板管理、系统管理、订单管理。 用户:…...

ubuntu下TFTP服务器搭建

tftp 命令的作用和 nfs 命令一样,都是用于通过网络下载东西到 DRAM 中,只是 tftp 命令 使用的 TFTP 协议, Ubuntu 主机作为 TFTP 服务器。因此需要在 Ubuntu 上搭建 TFTP 服务器, 需要安装 tftp-hpa 和 tftpd-hpa,命令…...

解决:ModuleNotFoundError: No module named ‘_sqlite3‘

报错: from _sqlite3 import * ModuleNotFoundError: No module named _sqlite3安装sqlite3支持组件: sudo apt-get install libsqlite3-dev进入之前下载的python包下,重新编译和安装Python ./configure --enable-loadable-sqlite-extensions make &a…...

技术债务的隐患:何时重构,何时妥协?

在快节奏的软件开发环境中,企业为了抢占市场或满足紧迫需求,往往不得不在短期内采取“捷径”来加速产品交付,这便引入了“技术债务”。短期内看似能迅速交付,但随着时间推移,这些未优化的代码和架构缺陷会逐渐累积&…...

c#Winform也可以跨平台了GTK框架GTKSystem.Windows.Forms

一、简介 >> 新版下载,问题求助 QQ群:1011147488 1032313876 236066073(满) Visual Studio原生开发,无需学习,一次编译,跨平台运行. C#桌面应用程序跨平台(windows、linux、…...

ABAP PDF预览

画个屏幕 PDF JPG TXT都可以参考预览,把二进制流传递给标准函数就行 *&---------------------------------------------------------------------* *& Report YDEMO2 *&---------------------------------------------------------------------* *&am…...

网络爬虫【爬虫库urllib】

我叫不三不四,很高兴见到大家,欢迎一起学习交流和进步 今天来讲一讲爬虫 urllib介绍 Urllib是Python自带的标准库,无须安装,直接引用即可。 Urllib是一个收集几个模块来使用URL的软件包,大致具备以下功能。 ● urlli…...

卷积神经网络 - 卷积层

卷积神经网络一般由卷积层、汇聚层和全连接层构成,本文我们来学习卷积层。 卷积层(Convolutional Layer)是卷积神经网络(CNN)的核心组件,专门用于处理具有网格结构的数据(如图像、音频、时间序…...

玩转 Tailwind CSS:深入解析函数与指令

玩转 Tailwind CSS:深入解析函数与指令 如果你正在使用 Tailwind CSS,可能已经习惯了各种 text-center、mt-4 这样的类名,但你知道吗?Tailwind 其实还隐藏着一套 强大的函数与指令系统,可以让你的代码更加优雅、可维护…...

Axure设计之下拉多选框制作教程C(中继器)

利用Axure制作下拉多选器组件可以极大地提升原型制作的效率和效果。以下是基于你提供的详细步骤的详细指导,帮助你在Axure中实现一个功能完善、高保真且可复用的下拉多选器组件。 一、案例预览 预览地址:https://pghy0i.axshare.com 实现效果包括&#…...

本地部署Jina AI Reader:用Docker打造你的智能解析引擎

本地部署Jina AI Reader:用Docker打造你的智能解析引擎 🌟 引言:为什么需要本地部署?📌 场景应用图谱🔧 部署指南(Linux环境)1. 环境准备2. Docker部署3. 验证服务状态 &#x1f680…...

Java基础语法练习42(基本绘图-基本的事件处理机制-小坦克的绘制-键盘控制坦克移动)

目录 一、图形的基本绘制 1.基本介绍: 2.入门代码如下: 3.常用图形的绘制, 示例代码如下: 二、坦克的绘制 三、事件处理机制 四、坦克的移动 一、图形的基本绘制 1.基本介绍: Component 类提供了两个和绘图相关最重要的方…...

RabbitMQ 入门

RabbitMQ 入门 1RabbitMQ 介绍 RabbitMQ 是信息传输的中间者。本质上,他从生产者(producers)接收消息,转发这些消息给消费者(consumers).换句话说,他能够按根据你指定的规则进行消息转发、缓冲…...

yolo环境 pytorch环境配置 CUDA安装

我的成功案例:首先安装python 3.12.9的conda虚拟环境 (如果不安装3.12的会报错误ModuleNotFoundError:没有名为“numpy._core”的模块) 然后安装11.8cuda (其实我是可以最高安装12.6的cuda但我实测,太高版…...

ESP32(4)TCP通信

本章重点讲解 lwIP 的 Socket接口如何配置 TCP客户端,并在此基础上实现收发功能。 TCP Client 连接流程 在实现 TCP 协议之前,用户需要按照以下步骤配置结构体 sockaddr_in 的成员变量,以便建立 TCPClient 连接: ①:…...

【从零开始学习计算机科学】软件测试(二)单元测试 与 集成测试

【从零开始学习计算机科学】软件测试(二)单元测试 与 集成测试 单元测试概述单元测试的内容单元测试的优点单元测试的停止准则单元测试的过程与文档管理单元测试的任务集成测试集成测试关注的问题模块分析集成测试与系统测试的区别集成测试与开发的关系集成测试的层次集成测试…...

数学建模:MATLAB循环神经网络

一、简述 1.循环神经网络 循环神经网络(RNN)是一种用于处理序列数据的神经网络。不同于传统的前馈神经网络,RNN在隐藏层中加入了自反馈连接,使得网络能够对序列中的每个元素执行相同的操作,同时保持一个“记忆”状态…...

EagleTrader为何重申重要数据前后2分钟禁止交易?

3月12日,美国公布了2月份的CPI数据。 美国2月未季调CPI年率录得2.8%,为去年11月来新低,低于市场预期的2.9%。 美国2月季调后CPI月率录得0.2%,为去年10月来新低,预期值为0.3%,前值为0.5%。 数据公布后&#…...

【Spring】声明式事务传播机制

1. 所有传播行为 REQUIRED(默认类型): 如果当前存在事务,则加入该事务;如果没有,则新建一个事务。适用于大多数业务场景。 SUPPORTS: 如果当前存在事务,则加入该事务;…...

个人blog系统 前后端分离 前端js后端go

系统设计: 1.使用语言:前端使用vue,并使用axios向后端发送数据。后端使用的是go的gin框架,并使用grom连接数据库实现数据存储读取。 2.设计结构: 最终展示:仅展示添加模块,其他模块基本相似 前…...

单元测试mock

一、背景 现在有A类,B类,C类,A类依赖B类,依赖C类,如果想要测试A类中的某个方法的业务逻辑。A类依赖其他类,则把其他类给mock,然后A类需要真实对象。这样就可以测试A类中的方法。 举例:Ticket类需要调用Flight类和Pas…...

OpenGL 将屏幕上的二维坐标转换为三维空间中的一个点

本文主要介绍将屏幕上的二维坐标转换为三维空间中的一个点,该点位于 近 平面上(即 Z 坐标为 -1)。 一、步骤概述 屏幕坐标到标准化设备坐标 (NDC): 将屏幕坐标 (x, y) 转换为 NDC 坐标系。NDC 到相机空间: 使用逆投影矩阵将 NDC 坐标转换到相…...

golang接口用法-代码案例

文章目录 Go语言中接口(interface)的含义接口的常见应用场景示例1示例2(Dog 和 Cat)使用场景-多数据库 Go语言中接口(interface)的含义 接口在Go语言中是一种类型,它定义了一组方法的集合。一个…...

ORA-12162: TNS:net service name is incorrectly specified

1.现象 SQL plus 连接实例报错,已确定实例是open状态。 [rootlocalhost ~]# su - oracle [oraclelocalhost ~]$ sqlplus / as sysdbaSQL*Plus: Release 19.0.0.0.0 - Production on Sat Mar 15 10:20:56 2025 Version 19.11.0.0.0Copyright (c) 1982, 2020, Orac…...

基于 Verilog 的时序设计:从理论到实践的深度探索

在数字电路设计领域,时序设计是一个至关重要的环节,它涉及到组合逻辑电路与时序逻辑电路的设计差异、时钟信号的运用以及触发器的工作原理等多个方面。本文将围绕基于 Verilog 的时序设计实验展开,详细阐述实验过程、代码实现以及结果分析,帮助读者深入理解时序设计的核心概…...

GreenKGC: A Lightweight Knowledge Graph Completion Method(论文笔记)

CCF等级:A 发布时间:2023年7月 代码位置 25年3月17日交 目录 一、简介 二、原理 1.整体 2.表示学习 3.特征修剪 4.决策学习 三、实验性能 1.主要结果 2.消融实验 四、结论和未来工作 一、简介 传统知识图谱补全方法中,嵌入维度…...

SSM基础专项复习5——Maven私服搭建(2)

系列文章 1、SSM基础专项复习1——SSM项目整合-CSDN博客 2、SSM基础专项复习2——Spring 框架(1)-CSDN博客 3、SSM基础专项复习3——Spring框架(2)-CSDN博客 4、SSM基础专项复习4——Maven项目管理工具(1&#xff…...

Linux中的epoll简单使用案例

I/O 多路复用允许一个进程或线程同时监控多个网络 sockets 的状态。它通过单个系统调用(select)来检查多个 sockets 是否有数据可读、可写或是否有异常。Linux 提供了多种 I/O 复用技术,包括上面提到的 select、以及 poll、epoll。 创建epol…...