go语言学习笔记1

news2024/11/17 15:38:06

go语言简介

​ GoLang是一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言;它可以在不损失应用程序性能的情况下极大的降低代码的复杂性,还可以发挥多核处理器同步多工的优点,并可解决面向对象程序设计的麻烦,并帮助程序设计师处理琐碎但重要的内存管理问题。相比于其他编程语言,简洁、快速、安全、并行、有趣、开源、内存管理、数组安全、编译迅速是其特色。

go语言特性

Go语言作为一门全新的静态类型开发语言具有以下的几种特性:

  1. 内置并发编程支持:

    ​ 使用协程(goroutine) 做为基本的计算单元。 轻松地创建协程。

    ​ 使用通道(channel) 来实现协程间的同步和通信。

  2. 内置了映射(map) 和切片(slice) 类型 。

  3. 支持多态(polymorphism)。

  4. 使用接口(interface) 来实现装盒(value boxing) 和反射(reflection)。

  5. 支持指针。

  6. 支持函数闭包(closure) 。

  7. 支持方法。

  8. 支持延迟函数调用(defer) 。

  9. 支持类型内嵌(type embedding) 。

  10. 支持类型推断(type deduction or type inference) 。

  11. 内存安全。

  12. 自动垃圾回收。

  13. 良好的代码跨平台性。

Go程序生成的二进制可执行文件常常拥有以下优点:

  1. 内存消耗少
  2. 执行速度快
  3. 启动快

最简单的程序

package main
import "fmt"// 我们需要使用fmt包中的Println()函数

func main() {
fmt.Println("Hello, world. 你好,世界! ")
}

go语言常用的命令

Go官方工具链工具要求所有的Go源代码文件必须以.go后缀结尾,假设上面展示的最简单的Go程序存放在一个名叫simplest-go-program.go的文件中。打开一个终端(控制台) 并进入上述源文件所在的目录, 然后运行

go run simplest-go-program.go

如果代码中有语法错误, 这些错误将输出在终端中。

注意:

  1. go run子命令并不推荐在正式的大项目中使用。 go run子命令只是一种方便的方式来运行简单的Go程序。 对于正式的项目, 最好使用go build或者go install子命令构建可执行程序文件来运行Go程序。
  2. 支持Go模块特性的Go项目的根目录下需要一个go.mod文件。 此文件可以使用go mod init子命令来生成。

其他命令

  • go vet子命令可以用来检查可能的代码逻辑错误(即警告)。

  • go fmt子命令来用同一种代码风格格式化Go代码。

  • go test子命令来运行单元和基准测试用例。

  • go doc子命令来(在终端中) 查看Go代码库包的文档。

  • go mod init example.com/myproject命令可以用来在当前目录中生成一个go.mod文件。 当前目录将被视为一个名为example.com/myproject的模块(即当前项目) 的根目录。

  • go mod tidy命令用来通过扫描当前项目中的所有代码来添加未被记录的依赖至go.mod文件或从go.mod文件中删除不再被使用的依赖。

  • go get命令用拉添加、 升级、 降级或者删除单个依赖。 此命令不如go mod tidy命令常用。

指针

go语言与C语言和C++语言一样也支持指针,但是Go中的指针相比C指针有很多限制 。一个指针变量指向了一个值的内存地址。类似于变量和常量,在使用指针前你需要声明指针。指针声明格式如下:

var var_name *var-type

var-type 为指针类型,var_name 为指针变量名,* 号用于指定变量是作为一个指针。以下是有效的指针声明:

var ip *int        /* 指向整型*/
var fp *float32    /* 指向浮点型 */

指针类型和值

一个非定义指针类型的字面形式为T, 其中T为一个任意类型。 类型T称为指针类型T的基类型(base type) 。 如果一个指针类型的基类型为T, 则我们可以称此指针类型为一个T指针类型

*int // 一个基类型为int的非定义指针类型。
**int // 一个多级非定义指针类型, 它的基类型为*int。
type Ptr *int // Ptr是一个定义的指针类型, 它的基类型为int。
type PP *Ptr // PP是一个定义的多级指针类型, 它的基类型为Ptr  

使用指针

获取一个指针值:

  • 可以使用内置函数new来为任何类型的值开辟一块内存并将此内存块的起始地址做为此值的地址返回。 假设T是任一类型, 则函数调用new(T)返回一个类型为*T的指针值。 存储在返回指针值所表示的地址处的值(可被看作是一个匿名变量) 为T的零值。
  • 我们也可以使用前置取地址操作符&来获取一个可寻址的值的地址。 对于一个类型为T的可寻址的值t, 我们可以用&t来取得它的地址。 &t的类型为*T

指针使用流程:

  • 定义指针变量。
  • 为指针变量赋值。
  • 访问指针变量中指向地址的值。

在指针类型前面加上 * 号(前缀)来获取指针所指向的内容。

package main

import "fmt"

func main() {
   var a int= 20   /* 声明实际变量 */
   var ip *int        /* 声明指针变量 */

   ip = &a  /* 指针变量的存储地址 */

   fmt.Printf("a 变量的地址是: %x\n", &a  )

   /* 指针变量的存储地址 */
   fmt.Printf("ip 变量储存的指针地址: %x\n", ip )

   /* 使用指针访问值 */
   fmt.Printf("*ip 变量的值: %d\n", *ip )
}

以上实例执行输出参考结果为(不同的电脑执行出的结果不一样,每次执行的结果也不一样):

a 变量的地址是: 20818a220
ip 变量储存的指针地址: 20818a220
*ip 变量的值: 20

前置解引用操作符来访问存储在一个指针所表示的地址处的值(即此指针所引用着的值) 。 比如, 对于基类型为T的指针类型的一个指针值p, 我们可以用p来表示地址p处的值。 此值的类型为T。 *p称为指针p的解引用。 解引用是取地址的逆过程。

package main

import "fmt"

func main() {
	p0 := new(int) // p0指向一个int类型的零值
	fmt.Println(p0) // (打印出一个十六进制形式的地址)
	fmt.Println(*p0) // 0
	
	x := *p0 // x是p0所引用的值的一个复制。
	p1, p2 := &x, &x // p1和p2中都存储着x的地址。
	// x、 *p1和*p2表示着同一个int值。
	fmt.Println(p1 == p2) // true
	fmt.Println(p0 == p1) // false
	p3 := &*p0 // <=> p3 := &(*p0)
	// <=> p3 := p0
	// p3和p0中存储的地址是一样的。
	fmt.Println(p0 == p3) // true
	*p0, *p1 = 123, 789
	fmt.Println(*p2, x, *p3) // 789 789 123
	
	fmt.Printf("%T, %T \n", *p0, x) // int, int
	fmt.Printf("%T, %T \n", p0, p1) // *int, *int
 }

上面的结果可以由这张图进行说明:

在这里插入图片描述

内存地址

一个内存地址表示操作系统管理的整个内存中的一个偏移量(相对于从整个内存的起始, 以字节计数)。

通常地, 一个内存地址用一个操作系统原生字(native word) 来存储。 一个原生字在32位操作系统上占4个字节, 在64位操作系统上占8个字节。 所以, 32位操作系统上的理论最大支持内存容量为4GB(1GB == 230字节) , 64位操作系统上的理论最大支持内存容量为264Byte, 即16EB(EB: 艾字节,1EB == 1024PB, 1PB == 1024TB, 1TB == 1024GB)。内存地址的字面形式常用整数的十六进制字面量来表示, 比如0x1234CDEF。

为了方便,简称内存地址为地址。

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

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

相关文章

2.ThreadLocalRandom

Random类及其局限性 一般情况下&#xff0c;我们都会使用java.util.Random来生成随机数&#xff08;Math.random()也是使用Random实例生成随机数&#xff09;。 示例 public static void main(String[] args) {Random random new Random();for (int i 0; i < 10; i) {S…

热搜第一!携程宣布每生一个娃奖5万!

6月30日&#xff0c;在线旅游平台携程集团宣布&#xff0c;他们全新推出一项针对全球员工的生育补贴政策。 从2023年7月1日开始&#xff0c;入职满3年的全球员工&#xff0c;无论你是男是女&#xff0c;每生育一个孩子&#xff0c;就将为你获得每年一万元的现金补贴。而这份补贴…

从vue2学习vue3

vue3与vue2的区别 Vue 3在写法上与Vue 2有一些区别&#xff0c;以下是一些常见的区别&#xff1a;引入方式&#xff1a;Vue 2使用Vue全局对象进行引入&#xff0c;而Vue 3使用createApp函数创建应用实例。组件注册&#xff1a;Vue 2中使用Vue.component全局方法或在选项中使用…

Python用if-else实现【猜数字】

文章目录 Python 猜数字案例代码实现&#xff1a;运行效果&#xff1a; Python 猜数字案例 设置一个范围1-100的随机整数变量&#xff0c;通过while循环&#xff0c;配合input语句&#xff0c;判断输入的数字是否等于随机数 无限次机会&#xff0c;直到猜中为止每一次猜不中&am…

1.Springboot基础篇笔记

Springboot基础篇 1.快速上手Springboot 1.基础配置 1.parent 通过配置指定父工程依赖为spring-boot-starter-paerent实现了版本管理的功能&#xff0c;再导入springboot整合其他技术的jar包即可 作用&#xff1a;指定jar包版本信息信息&#xff0c;避免依赖版本冲突 这个s…

理解 flask中request中form、data、json、values属性的区别

flask的request对象中关于请求参数的获取有几个不同的属性,例如 args、form、data、json。估计大部分人一开始也分不清什么情况下哪个属性有值,哪个属性没值,这篇文章全面整理了这几个属性之间的区别和使用场景。 flask.request对象其实是对HTTP请求的一种封装,我们知道HT…

Fidder抓包工具基础+postman调试测试

1、下载地址 汉化Fiddler Web Debugger(5.0.20192.25092)中文版 2、配置参数初始化 开启 fidder 百度即可 3、抓包 核心&#xff1a; 入参 出参 4、如何把包的数据放到postman发生请求 保存一个文件&#xff0c;选择格式 保存文件 自定义名称 将har 包托人 postman 即可 &…

华为OD机试真题B卷 Python 实现【箱子之形摆放】,附详细解题思路

目录 一、题目描述二、输入描述三、输出描述四、解题思路五、Python算法源码六、效果展示1、输入2、输出3、说明 一、题目描述 要求将一批箱子按从上到下以‘之’字形的顺序摆放在宽度为 n 的空地上&#xff0c;输出箱子的摆放位置&#xff0c;例如&#xff1a;箱子ABCDEFG&am…

Autosar诊断实战系列08-Dem与BswM在ECU运行期间究竟擦出了哪些火花

本文框架 前言1. Dem与BswM交互内容先睹为快2 Dem与BswM交互的配置开发2.1 ESH_DemInit Rule2.2 Dem_Shutdown的处理规则3. Dem在初始化及Shutdown期间的工作内容3.1 Dem初始化期间工作内容3.2 Dem_ShutDown期间工作内容前言 在本系列笔者将结合工作中对诊断实战部分的应用经验…

九齐NY8A051D硬件IR模块的配置和使用以及解码处理

写在前面 最近在群里有看到有小伙伴在问九齐的硬件IR模块&#xff0c;突然想起来我好像用过&#xff0c;找了半天才把项目找出来&#xff0c;写篇博客记录一下方便下次使用和寻找。 按道理来说九齐所有内置硬件IR模块的MCU都是可以用类似的方法配置和使用的&#xff0c;举一反…

packaged_task创建异步任务

本文将介绍基本的packaged_task的用法&#xff1a; 看完上述代码后一定有疑问&#xff1a; 为什么要有packaged_task&#xff1f; 解答&#xff1a;上文的线程通信代码如下&#xff1a; 功能主要是做了求两数之和&#xff0c;然而一般情况下&#xff0c;我们并不习惯这样编写子…

Hive(15):Table(表)DDL操作

1 Describe table Hive中的DESCRIBE table语句用于显示Hive中表的元数据信息 describe formatted [db_name.]table_name; describe extended [db_name.]table_name; 如果指定了EXTENDED关键字,则它将以Thrift序列化形式显示表的所有元数据。如果指定了FORMATTED关键字,则它…

大数据Doris(五十三):MySQL Dump 导出

文章目录 MySQL dump 导出 一、Dump导出案例 二、注意事项 MySQL Dump 导出 mysqldump是一个常用的 MySQL 数据库备份工具&#xff0c;它可以将 MySQL 数据库中的数据导出为 SQL 格式的文件&#xff0c;从而实现对数据的备份、迁移和恢复等操作。Doris 在0.15 之后的版本已…

Flutter 实现任意控件拖动功能

文章目录 前言一、如何实现&#xff1f;1、使用GestureDetector响应拖动事件2、使用Transform变换控件位置3、计算活动区域 二、完整代码三、使用示例1、基本用法 总结 前言 使用flutter开发是需要控件能拖动&#xff0c;比如画板中的元素&#xff0c;或者工具条&#xff0c;搜…

递归入门-数据结构和算法教程

什么是递归&#xff1f; 函数直接或间接调用自身的过程称为递归&#xff0c;相应的函数称为递归函数。使用递归算法&#xff0c;某些问题可以很容易地解决。这样的问题的示例是河内塔&#xff08;TOH&#xff09;、中序/前序/后序树遍历、图的DFS等。递归函数通过调用自身的副…

网络安全(黑客)自学建议

建议一&#xff1a;黑客七个等级 黑客&#xff0c;对很多人来说充满诱惑力。很多人可以发现这门领域如同任何一门领域&#xff0c;越深入越敬畏&#xff0c;知识如海洋&#xff0c;黑客也存在一些等级&#xff0c;参考知道创宇 CEO ic&#xff08;世界顶级黑客团队 0x557 成员…

基于微信小程序的英语单词记忆系统的设计与实现(论文+源码)_kaic

摘 要 当前时期&#xff0c;国内的经济获得了非常快速的发展&#xff0c;互联网技术在持续的创新和完善&#xff0c;教育教学方面也在不断的进步&#xff0c;教育全面深化改革在发展&#xff0c;并且移动互联网技术在教育领域获得了大量的实践以及应用。语言的全球化慢慢的变…

【算法】01背包和完全背包

文章目录 背包问题概览01背包二维dp数组写法一维dp数组写法 完全背包关于遍历顺序相关题目[416. 分割等和子集](https://leetcode.cn/problems/partition-equal-subset-sum/)[279. 完全平方数](https://leetcode.cn/problems/perfect-squares/)[518. 零钱兑换 II](https://leet…

【webrtc】vs2017 重新构建m98

配置了一台13900k的主机,需要重新配置webrtc 构建环境代码已经gclient sync 同步好了,打算重新构建:vs2017 的win10 sdk最大17763 vs2017 环境 set vs2017_install=S:\Program Files (x86)\Microsoft Visual Studio\2017\Communitywin10 SD

Python_上下文管理器

目录 上下文管理器类 多上下文管理器 contextmanager实现上下文管理器 上下文管理器(context manager)是 Python 编程中的重要概念&#xff0c;用于规定某个对象的使用范围。一旦进入或者离开该使用范围&#xff0c;会有特殊操作被调用 (比如为对象分配或者释放内存)。它的语…