Golang的基本使用

news2024/11/25 12:36:42

目录

变量的声明

Golang常用容器

defer

有趣的多态

结构体标签和reflect 反射

Golang最强的协程

channel

go可能造成的内存泄露

变量的声明

方法 1:有类型,有var,不赋值 在Golang中默认值为0

方法 2:无类型,有var,赋值

方法 3:无类型,无var,赋值

多变量声明

多变量声明,无类型无var

如下

package main

import (
	"fmt"
)

func main() {
	//var 用于声明变量
	var a int // 方法 1:有类型,有var,不赋值 在Golang中默认值为0
	fmt.Println("a=", a)

	var b = 0 //方法 2:无类型,有var,赋值
	fmt.Println("b=", b)

	c := 0 //方法 3:无类型,无var,赋值
	fmt.Println("c=", c)

	//多变量声明
	var d, e int = 1, 2 //
	fmt.Println("d=", d, "e=", e)

	//多变量声明,无类型无var
	f, g := "string", 3
	fmt.Println("f=", f, "e=", g)

}

常量 

定义后无法改变

Golang常用容器

静态数组(slice)

package main

import "fmt"

func main() {

	//数组,静态数组
	var arr [5]int
	arr[0] = 1
	arr[1] = 2
	arr[2] = 3
	arr[3] = 4
	arr[4] = 5
	fmt.Println(arr)      // 输出: [1 2 3 4 5]
	fmt.Println(len(arr)) // 输出: 5

}

动态数组(array)

跟静态数组的区别,就是 不用规定数组大小,自动分配自动扩容

package main

import "fmt"

func main() {
	//跟静态数组的区别,就是 不用规定数组大小,自动分配自动扩容
	slice := []int{1, 2, 3, 4, 5}
	fmt.Println(slice)      // 输出: [1 2 3 4 5]
	fmt.Println(len(slice)) // 输出: 5
}

自动扩容演示

slice两倍扩容

package main

import "fmt"

func main() {
	//跟静态数组的区别,就是 不用规定数组大小,自动分配自动扩容
	slice := []int{1, 2, 3, 4, 5}
	fmt.Println(slice)      // 输出: [1 2 3 4 5]
	fmt.Println(len(slice)) // 输出: 5
	fmt.Println(cap(slice)) //当前容量为5

	slice = append(slice, 6)
	fmt.Println(len(slice)) // 输出: 数据数量=6
	fmt.Println(cap(slice)) // 输出: 10 slice两倍扩容
}

字符串(string)

package main

import "fmt"

func main() {
	str := "Hello, World!"
	fmt.Println(str)         // 输出: Hello, World!
	fmt.Println(len(str))    // 输出: 13
	fmt.Printf("%s", str[0]) // 输出: H 
}

映射(map)

package main

import "fmt"

func main() {
	m := make(map[int]string)
	m[1] = "apple"
	m[2] = "banana"
	m[3] = "orange"
	for i := 1; i < 4; i++ {
		fmt.Printf("m=%s\n", m[i])
	}
}

defer

类似c++中的析构函数

defer作用:

        释放占用的资源

        捕捉处理异常

        输出日志

func main() {
	defer func() {
		fmt.Println("析构函数")
	}()
	fmt.Println("main start")
	//===
	//业务
	//===
	fmt.Println("main off")
}

当然Golang中有资源自动回收,不用自己析构,当然有特殊的例子下面讲了协程再说

有趣的多态

import "fmt"

// 两个类
type Student struct {
	age int
}

type Programmer struct {
	age int
}

// 同一调用
func whatJob(p Person) {
	p.job()
}

func growUp(p Person) {
	p.growUp()
}

// 一个万能接口
type Person interface { //intetface 万能变量
	job()
	growUp()
}

// Student 函数方法
func (p Student) job() {
	fmt.Println("I am a student.")
	return
}

func (p *Student) growUp() {
	p.age += 1
	return
}

// Programmer 函数方法
func (p Programmer) job() {
	fmt.Println("I am a programmer.")
	return
}

func (p *Programmer) growUp() {
	p.age += 10
	return
}

func main() {
	qcrao := Student{age: 18}
	whatJob(&qcrao)

	growUp(&qcrao)
	fmt.Println(qcrao)

	stefno := Programmer{age: 100}
	whatJob(&stefno)

	growUp(&stefno) //同一个函数,调用结果不同
	fmt.Println(stefno)
}

结构体标签和reflect 反射

import (
	"fmt"
	"reflect"
)

type resume struct {
	Name string `json:"电影" doc:"喜剧之王"`
}

func findDoc(stru interface{}) map[string]string {
	t := reflect.TypeOf(stru).Elem() //reflect 反射 逆推类型
	doc := make(map[string]string)

	for i := 0; i < t.NumField(); i++ {
		doc[t.Field(i).Tag.Get("json")] = t.Field(i).Tag.Get("doc")
	}

	return doc

}

func main() {
	var stru resume
	doc := findDoc(&stru)
	fmt.Printf("电影字段=%s\n", doc["电影"])
}

Golang最强的协程

package main

import (
	"fmt"
	"time"
)

func main() {
	go func() {
		fmt.Println("我是协程")
	}()

	fmt.Println("我是主协程")

	time.Sleep(1 * time.Second) // 等待一秒钟,让协程有足够的时间执行
}

身为一个cpp学者,当看见Golang写协程那么方便,异常兴奋

那么协程用什么与主协程通信呢?

channel

管道(channel)接收和发送数据都是阻塞的

package main

import (
	"fmt"
	"time"
)

func main() {
	c := make(chan int) //创建管道(channel),而且接收和发送数据都是阻塞的
	go func() {
		fmt.Println("我是协程")
		c <- 666 //向管道内写入666
	}()

	a := <-c //管道类读出
	fmt.Println("我是主协程")
	fmt.Println("a=", a)

	time.Sleep(1 * time.Second) // 等待一秒钟,让协程有足够的时间执行
}

go可能造成的内存泄露

func main() {
    ch := func() <-chan int {
        ch := make(chan int)
        go func() {
            for i := 0; ; i++ {
                ch <- i
            }
        } ()
        return ch
    }()

    for v := range ch {
        fmt.Println(v)
        if v == 5 {
            break
        }
    }
}

使用 valgrind 运行 程序,发现 协程内存并没有回收

问题:

上面的程序中后台Goroutine向管道输入自然数序列,main函数中输出序列。

但是当break跳出for循环的时候,后台Goroutine就处于无法被回收的状态了。

因为 Goroutine还在向管道中写数据,主协程已经退出

改正:

使用context

package main

import (
	"context"
	"fmt"
)

func main() {
	//WithCancel(ctx Context, cancel CancelFunc)=(名 Context,处理函数 CancelFunc)
	ctx, cancel := context.WithCancel(context.Background()) //context.Background() 处理 Goroutine

	ch := func(ctx context.Context) <-chan int {
		ch := make(chan int)
		go func() {
			for i := 0; ; i++ {
				select {
				case <-ctx.Done():
					return
				case ch <- i:
				}
			}
		}()
		return ch
	}(ctx)

	for v := range ch {
		fmt.Println(v)
		if v == 5 {
			cancel()
			break
		}
	}
}

当main函数在break跳出循环时,通过调用 context 来通知后台Goroutine退出

这样就避免了Goroutine的泄漏。 

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

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

相关文章

C语言 数组——查找算法的函数实现

目录 线性查找&#xff08;Linear Search&#xff09; 线性查找的性能 猜数游戏 二分查找&#xff08;Binary Search&#xff09; 并非吹毛求疵&#xff0c;鸡蛋里挑骨头 二分查找的性能 线性查找&#xff08;Linear Search&#xff09; 不 要求数据表是已排好序的  …

AI巨头争相与Reddit合作:为何一个古老的论坛成为AI训练的“宝藏”?

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

这种电脑原来这么耗电……震惊了粉丝小姐姐

前言 在今年1月份的时候&#xff0c;一位来自重庆的小姐姐加了小白&#xff0c;咨询电脑的问题&#xff1a; 哦豁&#xff0c;这个电脑看着确实闪闪发光&#xff0c;是真的很漂亮&#xff5e;&#xff08;嗯&#xff0c;小姐姐也很漂亮&#xff09; 电脑无法开机&#xff0c;按…

华为云发布ServiceStage:内置优秀业界实践「云应用管理和运维」模板

迅猛发展的业务让企业IT系统架构愈加复杂&#xff0c;为满足业务快速迭代的需求&#xff0c;重点企业完成从传统单体应用架构到分布式微服务架构的升级。微服务架构虽可提升研发效率&#xff0c;但数量庞大的微服务实例间错综复杂的依赖关系无疑增加了部署运维难度。 同时&…

Go源码--sync库(1)sync.Once和

简介 这篇主要介绍 sync.Once、sync.WaitGroup和sync.Mutex sync.Once once 顾名思义 只执行一次 废话不说 我们看源码 英文介绍直接略过了 感兴趣的建议读一读 获益匪浅 其结构体如下 Once 是一个严格只执行一次的object type Once struct {// 建议看下源码的注解&#xf…

汇编语言(STC89C52)

指令是计算机计算CPU根据人的意图来执行某种操作的命令。一台计算机所执行的全部指令的集合&#xff0c;称为这个CPU的指令系统。而想要使计算机按照人们的要求完成一项工作&#xff0c;就必须让CPU按顺序执行预设的操作&#xff0c;即逐条执行人们编写的指令。这种按照人民要求…

暴雨信息液冷计算解决方案亮相CCIG 2024

5月24日&#xff0c;2024中国图象图形大会&#xff08;CCIG&#xff09;在陕西西安正式开幕。作为涵盖图像图形各专业领域的综合性的全国性学术会议&#xff0c;CCIG面向开放创新、交叉融合的发展趋势&#xff0c;为图像图形相关领域的专家学者和产业界的同仁&#xff0c;搭建了…

本是梦中人,常作花下客。心中自往来,知我有几个。

我们总是喜欢拿“顺其自然”来敷衍人生道路上的荆棘坎坷&#xff0c;却很少承认&#xff0c;真正的顺其自然&#xff0c; 其实是竭尽所能之后的不强求&#xff0c; 而非两手一摊的不作为。 一花凋零荒芜不了整个春天&#xff0c; 一次挫折也荒废不了整个人生。 多年后&#x…

头歌openGauss-存储过程第1关:创建存储过程

编程要求 1、创建第1个存储过程&#xff0c;并调用&#xff1b; 1&#xff09;创建存储过程&#xff0c;查询emp表数据&#xff1b; 2&#xff09;调用存储过程&#xff1b; --创建存储过程&#xff0c;获得计算机&#xff08;cs&#xff09;系学生选课情况并将结果写入临时表t…

免费wordpress中文主题

免费大图wordpress主题 首页是一张大图的免费wordpress主题模板。简洁实用&#xff0c;易上手。 https://www.jianzhanpress.com/?p5857 免费WP模板下载 顶部左侧导航条的免费WP模板&#xff0c;后台简洁&#xff0c;新手也可以下载使用。 https://www.jianzhanpress.com/…

d20(184-190)-勇敢开始Java,咖啡拯救人生

目录 网络通信 网络通信三要素&#xff08;IP地址&#xff0c;端口号&#xff0c;协议 IP地址 InetAddress 端口号 协议 传输层的两个通信协议 UDP通信 java.net.Datagramsocket类 客户端 服务端 UDP通信多收多发 客户端 服务端 TCP通信 java.net.Socket类 客…

【MYSQL】分数排名

表: Scores ---------------------- | Column Name | Type | ---------------------- | id | int | | score | decimal | ---------------------- id 是该表的主键&#xff08;有不同值的列&#xff09;。 该表的每一行都包含了一场比赛的分数。Score 是…

Go微服务: 日志系统ELK的应用

概述 基于前文&#xff0c;我们已经了解并搭建完成ELK的所有环境了&#xff0c;现在我们来结合应用程序来使用ELK参考前文&#xff1a;https://active.blog.csdn.net/article/details/138898538 封装日志模块 在通用工具模块: gitee.com/go-micro-services/common 这个包是通…

【C语言】——函数栈帧的创建与销毁

函数栈帧的创建与销毁 本文主要讲解了函数调用过程中其栈帧的创建与销毁&#xff0c;内容干货较多&#xff0c;希望大家认真品味。 使用C语言进行函数调用时&#xff0c;是否会有很多疑问&#xff1a; 1.局部变量是如何创建的&#xff1f; 2.局部变量在未初始化的情况下&#x…

物理服务器介绍

物理服务器介绍 概述分类按服务器应用分类按服务器结构分类塔式服务器机架式服务器刀片式服务器机架式服务器与刀片式服务器的对比按处理器个数分类按处理器架构分类 主板概述工作原理物理结构技术参数 CPU概述工作原理指令集相关技术技术参数主流产品 内存概述类型相关技术技术…

安卓分身大师4.6.0解锁会员安卓14可用机型伪装双开多开

需登录解锁会员功能&#xff0c;除了加速进入不能&#xff0c; 其他主要功能都是可以使用&#xff0c;由于验证较多一些功能需要特定操作使用&#xff0c;进行伪装时请不要直接伪装&#xff0c;先生成成功后再进行自定义伪装&#xff01;链接&#xff1a;https://pan.baidu.com…

Transformer详解(3)-多头自注意力机制

attention multi-head attention pytorch代码实现 import math import torch from torch import nn import torch.nn.functional as Fclass MultiHeadAttention(nn.Module):def __init__(self, heads8, d_model128, droput0.1):super().__init__()self.d_model d_model # 12…

通过el-tree自定义渲染网页版工作目录,实现鼠标悬浮显示完整名称、用icon区分文件和文件夹等需求

目录 一、通过el-tree自定义渲染网页版工作目录 1.1、需求介绍 1.2、使用el-tree生成文档目录 1.2.1、官方基础用法 ①效果 ②代码&#xff1a; 1.2.2、自定义文档目录&#xff08;实现鼠标悬浮显示完整名称、用icon区分文件和文件夹&#xff09; ①效果&#xff08;直接效…

JavaScript表达式和运算符

表达式 表达式一般由常量、变量、运算符、子表达式构成。最简单的表达式可以是一个简单的值。常量或变量。例&#xff1a;var a10 运算符 运算符一般用符号来表示&#xff0c;也有些使用关键字表示。运算符由3中类型 1.一元运算符&#xff1a;一个运算符能够结合一个操作数&…

YOLOv8_seg的训练、验证、预测及导出[实例分割实践篇]

实例分割数据集链接,还是和目标检测篇一样,从coco2017val数据集中挑出来person和surfboard两类:链接:百度网盘 请输入提取码 提取码:3xmm 1.实例分割数据划分及配置 1.1实例分割数据划分 从上面得到的数据还不能够直接训练,需要按照一定的比例划分训练集和验证集,并按…