struct用来自定义复杂数据结构,相当于其他面向对象语言中的Class。
语法:
type 标识符 struct{
field1 type
field2 type
}
如:
type Student struct{
Name string
Age int
Score int
}
var stu Student
var stu *Student = new(Student)
var stu *Student = &Student{}
其中,后两种返回的都是指向结构体的指针,访问形式如下: stu.Name
、stu.Age
和stu.Score
或者 (*stu).Name
、(*stu).Age
、(*stu).Score
。
struct中的所有字段在内存是连续的,布局如下:
golang中的struct没有构造函数,一般可以使用工厂模式来解决这个问题。
package model
import "fmt"
type student struct {
name string
age int
}
func NewStudent(name string, age int) *student {
return &student{
name: name,
age: age,
}
}
func (s student)Print() {
fmt.Println(s.name, s.age)
}
package main
import (
"golang_learning/model"
"fmt"
"strings"
)
func main() {
s := model.NewStudent("sam", 18)
s.Print()
fmt.Println(strings.Repeat("*", 10))
}
我们可以为struct中的每个字段,写上一个tag。这个tag可以通过反射的机制获取到,最常用的场景就是json序列化和反序列化。
type student struct {
Name string "this is name field"
Age int "this is age field"
}
还有一种场景是,由于golang中的字段大写才能导出,到与其他语言交互时,字段名多为小写,这个时候也可以使用tag来解决。
type student struct {
Name string "name"
Age int "age"
}
type Wheel struct {
Name string
Size int
}
type Car struct {
Wheel
Comp string
Date time.Time
int
}
只要冲突的字段不再同一个级别,就不会panic;可以通过明确指定来访问。
type Wheel struct {
Name string
Size int
}
type Car struct {
Wheel
Comp string
Date time.Time
Size int
}
w := Wheel{"w", 1}
c := Car{w, "auto", time.Now(), 20}
fmt.Println("%v", w)
fmt.Println("%v", c)
fmt.Println(c.Size)
fmt.Println(c.Wheel.Size)
// 20
// 1
Golang中的方法是作用在特定类型的变量上,因此自定义类型,都可以有方法,而不仅仅是struct。如:
package main
import (
"fmt"
)
type Int int
func (i Int)print() {
fmt.Println(i)
}
func main() {
i := Int(99)
i.print()
}
// 99
定义:func (recevier type) methodName(参数列表)(返回值列表){}
另外,方法的访问控制,通过大小写控制。
方法和函数的区别:
结构体是值类型的,如果需要修改其内部的值,需要使用指针。
如果一个struct嵌套了另一个匿名结构体,那么这个结构可以直接访问匿名结构体的方法,从而实现了继承。
如果一个struct嵌套了多个匿名结构体,那么这个结构可以直接访问多个匿名结构体的方法,从而实现了多重继承。
如果一个struct嵌套了另一个有名结构体,那么这个模式就叫组合。
如果一个变量实现了String()这个方法,那么fmt.Println默认会调用这个
变量的String()进行输出。
package main
import (
"fmt"
"strconv"
)
type student struct{
name string
age int
}
func (s student)String() string{
return "name: " + s.name + ", age: " + strconv.Itoa(s.age)
}
func main() {
s := student{"lee", 18}
fmt.Println(s)
fmt.Printf("%s", s)
}
// name: lee, age: 18
// name: lee, age: 18
Interface类型可以定义一组方法,但是这些不需要实现。并且interface不能
包含任何变量。
interface类型默认是一个指针
type example interface{
Method1(参数列表) 返回值列表
Method2(参数列表) 返回值列表
...
}
var a example
a.Method1()
implement
类似的关键字一种事物的多种形态,都可以按照统一的接口进行操作
一个接口可以嵌套在另外的接口,比如:
type ReadWrite interface {
Read(b int) bool
Write(b int) bool
}
type Lock interface {
Lock()
Unlock()
}
type File interface {
ReadWrite
Lock
Close()
}
由于接口是一般类型,不知道其具体类型,如果要转换成具体类型,可以使用下面的方法进行转换:
var t int
var x interface{}
x = t
y, ok := x.(int) // 转成int
func classifier(items ...interface{}) {
for i, x := range items {
switch x.(type) {
case bool:
fmt.Printf("param #%d is a bool\n", i)
case float64:
fmt.Printf("param #%d is a float64\n", i)
case int, int64:
fmt.Printf("param #%d is an int\n", i)
case nil:
fmt.Printf("param #%d is nil\n", i)
case string:
fmt.Printf("param #%d is a string\n", i)
default:
fmt.Printf("param #%d’s type is unknown\n", i)
}
}
}
空接口没有任何方法,所以所有类型都实现了空接口。
var a int
var b interface{}
b = a
判断一个变量是否实现了指定接口:
type Stringer interface {
String() string
}
var v MyStruct
if sv, ok := v.(Stringer); ok {
fmt.Printf("v implements String():%s\n", sv.String())
}
变量slice和接口slice之间赋值操作
变量slice和接口slice之间赋值操作,应该使用for range
var a []int
var b []interface{}
// b = a //error!!!
for index, value := range a{
b[index] = value
}
fmt.Println(b)
原网址: 访问
创建于: 2022-08-18 13:39:07
目录: default
标签: 无
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
java windows火焰图_mob64ca12ec8020的技术博客_51CTO博客 - 在windows下不可行,不知道作者是怎样搞的 监听SpringBoot 服务启动成功事件并打印信息_监听springboot启动完毕-CSDN博客 SpringBoot中就绪探针和存活探针_management.endpoint.health.probes.enabled-CSDN博客 u2u转换板 - 嘉立创EDA开源硬件平台 Spring Boot 项目的轻量级 HTTP 客户端 retrofit 框架,快来试试它!_Java精选-CSDN博客 手把手教你打造一套最牛的知识笔记管理系统! - 知乎 - 想法有重合-理论可参考 安宇雨 闲鱼 机械键盘 客制化 开贴记录 文本 linux 使用find命令查找包含某字符串的文件_beijihukk的博客-CSDN博客_find 查找字符串 ---- mac 也适用 安宇雨 打字音 记录集合 B站 bilibili 自行搭建 开坑 真正的客制化 安宇雨 黑苹果开坑 查找工具包maven pom 引用地 工具网站 Dantelis 介绍的玩轴入坑攻略 --- 关于轴的一些说法 --- 非官方 ---- 心得而已 --- 长期开坑更新 [本人问题][新开坑位]关于自动化测试的工具与平台应用 机械键盘 开团 网站记录 -- 能做一个收集的程序就好了 不过现在没时间 -- 信息大多是在群里发的 - 你要让垃圾佬 都去一个地方看难度也是很大的 精神支柱 [超级前台]sprinbboot maven superdesk-app 记录 [信息有用] [环境准备] [基本完成] [sebp/elk] 给已创建的Docker容器增加新的端口映射 - qq_30599553的博客 - CSDN博客 [正在研究] Elasticsearch, Logstash, Kibana (ELK) Docker image documentation elasticsearch centos 安装记录 及 启动手记 正式服务器 39 elasticsearch 问题合集 不断更新 6.1.1 | 6.5.1 两个版本 博客程序 - 测试 - bug记录 等等问题 laravel的启动过程解析 - lpfuture - 博客园 OAuth2 Server PHP 用 Laravel 搭建带 OAuth2 验证的 RESTful 服务 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区 利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法 - 煮茶的博客 - SegmentFault 思否 使用 OAuth2-Server-php 搭建 OAuth2 Server - 午时的海 - 博客园 基于PHP构建OAuth 2.0 服务端 认证平台 - Endv - 博客园 Laravel 的 Artisan 命令行工具 Laravel 的文件系统和云存储功能集成 浅谈Chromium中的设计模式--终--Observer模式 浅谈Chromium中的设计模式--二--pre/post和Delegate模式 浅谈Chromium中的设计模式--一--Chromium中模块分层和进程模型 DeepMind 4 Hacking Yourself README.md update 20211011
Laravel China 简书 知乎 博客园 CSDN博客 开源中国 Go Further Ryan是菜鸟 | LNMP技术栈笔记 云栖社区-阿里云 Netflix技术博客 Techie Delight Linkedin技术博客 Dropbox技术博客 Facebook技术博客 淘宝中间件团队 美团技术博客 360技术博客 古巷博客 - 一个专注于分享的不正常博客 软件测试知识传播 - 测试窝 有赞技术团队 阮一峰 语雀 静觅丨崔庆才的个人博客 软件测试从业者综合能力提升 - isTester IBM Java 开发 使用开放 Java 生态系统开发现代应用程序 pengdai 一个强大的博主 HTML5资源教程 | 分享HTML5开发资源和开发教程 蘑菇博客 - 专注于技术分享的博客平台 个人博客-leapMie 流星007 CSDN博客 - 舍其小伙伴 稀土掘金 Go 技术论坛 | Golang / Go 语言中国知识社区
最新评论