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

Go语言语法基础

Go语言语法基础

  • 1.Go项目构建及编译
  • 2.下划线的用处
  • 3.Go语言变量与常量
    • 变量命名规范
    • 变量声明与初始化
    • 常量
  • 4.Go语言基本数据类型
    • 整型
    • 浮点型
    • 复数
    • 布尔型
    • 指针
    • 字符串
      • 窥探字符串类型
      • 字符串内建函数
      • 字符串和数字的转换

1.Go项目构建及编译

一个Go工程中主要包含以下三个目录:

src:源代码文件
pkg:包文件
bin:相关bin文件

我们可以引用别人的包也可以发布自己的包,但是为了防止不同包的项目名冲突,我们通常使用顶级域名来作为包名的前缀,这样就不担心项目名冲突的问题了

因为不是每个个人开发者都拥有自己的顶级域名,所以目前流行的方式是使用个人的github用户名来区分不同的包:

举个例子:张三和李四都有一个名叫studygo的项目,那么这两个包的路径就会是:

import "github.com/zhangsan/studygo"

和:

import "github.com/lisi/studygo"

2.下划线的用处

1、下划线在import中

当导入一个包时,该包下的文件里所有init()函数都会被执行,然而,有些时候我们并不需要把整个包都导入进来,仅仅是是希望它执行init()函数而已。这个时候就可以使用 import 引用该包。即使用import _ 包路径只是引用该包,仅仅是为了调用init()函数,无法通过包名来调用包中的其他函数

2、下划线在代码中

下划线意思是忽略这个变量,意思是那个位置本应赋给某个值,但是咱们不需要这个值,这样编译器可以更好的优化,任何类型的单个值都可以丢给下划线,例如:

package mainimport ("os"
)func main() {buf := make([]byte, 1024)f, _ := os.Open("/Users/***/Desktop/text.txt")defer f.Close()for {n, _ := f.Read(buf)if n == 0 {break    }os.Stdout.Write(buf[:n])}
}

3.Go语言变量与常量

变量命名规范

1、Go语言中的函数名、变量名、常量名、类型名、语句标号和包名等所有的命名,都遵循一个简单的命名规则:一个名字必须以一个字母(Unicode字母)或下划线开头,后面可以跟任意数量的字母、数字或下划线

2、大写字母和小写字母是不同的:heapSortHeapsort是两个不同的名字

3、如果一个名字是在函数内部定义,那么它就只在函数内部有效。如果是在函数外部定义,那么将在当前包的所有文件中都可以访问。

名字的开头字母的大小写决定了名字在包外的可见性。如果一个名字是大写字母开头的,那么它将是导出的,也就是说可以被外部的包访问,例如fmt包的Printf函数就是导出的,可以在fmt包外部访问。包本身的名字一般总是用小写字母

4、通常来说,如果一个名字的作用域比较大,生命周期也比较长,那么用长的名字将会更有意义

5、Go语言程序员推荐使用 驼峰式 命名,当名字由几个单词组成时优先使用大小写分隔,而不是优先用下划线分隔。因此,在标准库有QuoteRuneToASCIIparseRequestLine这样的函数命名

变量声明与初始化

Go语言主要有四种类型的声明语句:varconsttypefunc,分别对应变量、常量、类型和函数实体对象的声明

go语言中还支持批量变量声明,例如:

var (a stringb intc boold float32
)

var声明语句可以创建一个特定类型的变量,然后给变量附加一个名字,并且设置变量的初始值。语法如下:

var 变量名字 类型 = 表达式

其中类型= 表达式两个部分可以省略其中的一个。如果省略的是类型信息,那么将根据初始化表达式来推导变量的类型信息。如果初始化表达式被省略,那么将用零值初始化该变量,例如:

func main() {var s stringvar d = 12fmt.Println(s)fmt.Println(d)
}

在函数内部,有一种称为简短变量声明语句的形式可用于声明和初始化局部变量。它以“名字 := 表达式”形式声明变量,变量的类型根据表达式来自动推导,例如:

func main() {i := 100fmt.Println(i)
}

因为简洁和灵活的特点,简短变量声明被广泛用于大部分的局部变量的声明和初始化

这里有一个比较微妙的地方:简短变量声明左边的变量可能并不是全部都是刚刚声明的。如果有一些已经在相同的词法域声明过了,那么简短变量声明语句对这些已经声明过的变量就只有赋值行为

例如:

在下面的代码中,第一个语句声明了in和err两个变量。在第二个语句只声明了out一个变量,然后对已经声明的err进行了赋值操作

in, err := os.Open(infile)
// ...
out, err := os.Create(outfile)

常量

一个常量的声明语句定义了常量的名字,和变量的声明语法类似,常量的值不可修改,这样可以防止在运行期被意外或恶意的修改

所有常量的运算都可以在编译期完成,这样可以减少运行时的工作,也方便其他编译优化。当操作数是常量时,一些运行时的错误也可以在编译时被发现,例如整数除零、字符串索引越界、任何导致无效浮点数的操作等

常量间的所有算术运算、逻辑运算和比较运算的结果也是常量,对常量的类型转换操作或以下函数调用都是返回常量结果:len、cap、real、imag、complex和unsafe.Sizeof

iota 常量生成器

iota是go语言的常量计数器,只能在常量的表达式中使用。 iota在const关键字出现时将被重置为0。const中每新增一行常量声明将使iota计数一次

例如:周日将对应0,周一为1,如此等等

type Weekday intconst (Sunday Weekday = iotaMondayTuesdayWednesdayThursdayFridaySaturday
)

我们也可以在复杂的常量表达式中使用iota,下面是一个更复杂的例子,每个常量都是1024的幂:

const (_ = 1 << (10 * iota)KiB // 1024MiB // 1048576GiB // 1073741824TiB // 1099511627776             (exceeds 1 << 32)PiB // 1125899906842624EiB // 1152921504606846976ZiB // 1180591620717411303424    (exceeds 1 << 64)YiB // 1208925819614629174706176
)

4.Go语言基本数据类型

整型

Go语言同时提供了有符号和无符号类型的整数运算。有int8、int16、int32和int64四种截然不同大小的有符号整数类型,分别对应8、16、32、64bit大小的有符号整数,与此对应的是uint8、uint16、uint32和uint64四种无符号整数类型

还有两种一般对应特定CPU平台机器字大小的有符号和无符号整数intuint;其中int是应用最广泛的数值类型

无符号数往往只有在位运算或其它特殊的运算场景才会使用,就像bit集合、分析二进制文件格式或者是哈希和加密操作等。它们通常并不用于仅仅是表达非负数量的场合

最后,还有一种无符号的整数类型uintptr,没有指定具体的bit大小但是足以容纳指针。uintptr类型只有在底层编程时才需要,特别是Go语言和C语言函数库或操作系统接口相交互的地方

算术运算符+、-、*和/可以适用于整数、浮点数和复数,但是取模运算符%仅用于整数间的运算

对于每种类型T,如果转换允许的话,类型转换操作T(x)将x转换为T类型,例如:

func main() {f := 3.141 // a float64i := int(f)fmt.Println(f, i) // "3.141 3"f = 1.99fmt.Println(int(f)) // "1"
}

任何大小的整数字面值都可以用以0开始的八进制格式书写,例如0666;或用以0x0X开头的十六进制格式书写,例如0xdeadbeef。十六进制数字可以用大写或小写字母。如今八进制数据通常用于POSIX操作系统上的文件访问权限标志,十六进制数字则更强调数字值的bit位模式

当使用fmt包打印一个数值时,我们可以用%d、%o或%x参数控制输出的进制格式,就像下面的例子:

func main() {o := 0666fmt.Printf("%d %[1]o %#[1]o\n", o) // "438 666 0666"x := int64(0xdeadbeef)fmt.Printf("%d %[1]x %#[1]x %#[1]X\n", x)// Output:// 3735928559 deadbeef 0xdeadbeef 0XDEADBEEF
}

请注意fmt的两个使用技巧:

1、通常Printf格式化字符串包含多个%参数时将会包含对应相同数量的额外操作数,但是%之后的[1]副词告诉Printf函数再次使用第一个操作数

2、第二,%后的#副词告诉Printf在用%o、%x或%X输出时生成0、0x或0X前缀

浮点型

Go语言提供了两种精度的浮点数,float32和float64

一个float32类型的浮点数可以提供大约6个十进制数的精度,而float64则可以提供约15个十进制数的精度;通常应该优先使用float64类型

小数点前面或后面的数字都可能被省略(例如.707或1.)。很小或很大的数最好用科学计数法书写,通过e或E来指定指数部分:

const Avogadro = 6.02214129e23  // 阿伏伽德罗常数
const Planck   = 6.62606957e-34 // 普朗克常数

例子:打印e的幂,打印精度是小数点后三个小数精度和8个字符宽度:

for x := 0; x < 8; x++ {fmt.Printf("x = %d e^x = %8.3f\n", x, math.Exp(float64(x)))
}

复数

Go语言提供了两种精度的复数类型:complex64complex128,分别对应float32float64两种浮点数精度。内置的complex函数用于构建复数,内建的realimag函数分别返回复数的实部和虚部:

func main() {var x complex128 = complex(1, 2) // 1+2ivar y complex128 = complex(3, 4) // 3+4ifmt.Println(x * y)               // "(-5+10i)"fmt.Println(real(x * y))         // "-5"fmt.Println(imag(x * y))         // "10"
}

上面x和y的声明语句还可以简化:

x := 1 + 2i
y := 3 + 4i

如果一个浮点数面值或一个十进制整数面值后面跟着一个i,例如3.141592i或2i,它将构成一个复数的虚部,复数的实部是0:

fmt.Println(1i * 1i) // "(-1+0i)"

另外我,复数也可以用==和!=进行相等比较。只有两个复数的实部和虚部都相等的时候它们才是相等的

布尔型

一个布尔类型的值只有两种:true和false

在Go语言中,布尔值并不会隐式转换为数字值0或1

指针

一个指针的值是另一个变量的地址。一个指针对应变量在内存中的存储位置。通过指针,我们可以直接读或更新对应变量的值,而不需要知道该变量的名字

如果用“var x int”声明语句声明一个x变量,那么&x表达式(取x变量的内存地址)将产生一个指向该整数变量的指针,指针对应的数据类型是*int,指针被称之为“指向int类型的指针

func main() {x := 1p := &xfmt.Println(*p) // "1"*p = 2fmt.Println(x) // "2"
}

任何类型的指针的零值都是nil。如果p指向某个有效变量,那么p != nil测试为真。指针之间也是可以进行相等测试的,只有当它们指向同一个变量或全部是nil时才相等

func main() {var x, y intfmt.Println(&x == &x, &x == &y, &x == nil) // "true false false"
}

字符串

窥探字符串类型

因为字符串是不可修改的,因此尝试修改字符串内部数据的操作也是被禁止的,例如:

s[0] = 'L'

在一个双引号包含的字符串中,可以用以反斜杠\开头的转义序列插入任意的数据。下面的换行、回车和制表符等是常见的ASCII控制代码的转义方式:

\a      响铃
\b      退格
\f      换页
\n      换行
\r      回车
\t      制表符
\v      垂直制表符
\'      单引号
\"      双引号
\\      反斜杠

使用反引号代替双引号,就可以定义一个多行字符串:

func main() {const GoUsage = `Go is a tool for managing Go source code.Usage:go command [arguments]
...`fmt.Println(GoUsage)
}

字符串内建函数

例如内置的len函数可以返回一个字符串中的字节数目:

func main() {s := "hello, world"fmt.Println(len(s)) // "12"d := "你好,世界"fmt.Println(len(d)) // "15"
}

常用操作:

方法介绍
len(str)求长度
+或fmt.Sprintf拼接字符串
strings.Split分割
strings.Contains判断是否包含
strings.HasPrefix,strings.HasSuffix前缀/后缀判断
strings.Index(),strings.LastIndex()子串出现的位置
strings.Join(a[]string, sep string)join操作

字符串和数字的转换

将一个整数转为字符串,一种方法是用fmt.Sprintf返回一个格式化的字符串;另一个方法是用strconv.Itoa

func main() {x := 123y := fmt.Sprintf("%d", x)fmt.Println(y, strconv.Itoa(x)) // "123 123"
}

如果要将一个字符串解析为整数,可以使用strconv包的Atoi或ParseInt函数,还有用于解析无符号整数的ParseUint函数:

func main() {x, _ := strconv.Atoi("123")y, _ := strconv.ParseInt("123", 10, 64)fmt.Println(x)fmt.Println(y)
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 蓝禾,汤臣倍健,三七互娱,得物,顺丰,快手,游卡,oppo,康冠科技,途游游戏,埃科光电25秋招内推
  • GNU链接器(LD):设置入口点(ENTRY命令)的用法及实例解析
  • 【python】requests 库 源码解读、参数解读
  • 使用 Python 模拟光的折射,反射,和全反射
  • 【技术解析】wx.request 封装:优化小程序网络请求的最佳实践
  • 人工智能面试题(Artificial Intelligence Algorithm Interview Questions)
  • 【深度学习】03-神经网络3-1梯度下降网络优化方法
  • 在Java中 String能存储多少个字符?
  • 前端——表单标签样式
  • 使用Python实现图形学曲线和曲面的B样条曲线算法
  • 通过 Xshell 无法连接到 Ubuntu
  • 计算机二级C语言练习题
  • 【AI写代码】使用 ChatGPT 写 ila
  • 【Oauth2整合gateway网关实现微服务单点登录】
  • pycharm恢复两边侧边栏常驻显示
  • 【Redis学习笔记】2018-06-28 redis命令源码学习1
  • Akka系列(七):Actor持久化之Akka persistence
  • Consul Config 使用Git做版本控制的实现
  • CSS 三角实现
  • ES2017异步函数现已正式可用
  • IndexedDB
  • javascript面向对象之创建对象
  • JAVA多线程机制解析-volatilesynchronized
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • Python学习之路13-记分
  • spring security oauth2 password授权模式
  • springMvc学习笔记(2)
  • 诡异!React stopPropagation失灵
  • 漫谈开发设计中的一些“原则”及“设计哲学”
  • 前端_面试
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 学习HTTP相关知识笔记
  • 一起来学SpringBoot | 第三篇:SpringBoot日志配置
  • 硬币翻转问题,区间操作
  • Nginx实现动静分离
  • 翻译 | The Principles of OOD 面向对象设计原则
  • 移动端高清、多屏适配方案
  • ​一些不规范的GTID使用场景
  • #07【面试问题整理】嵌入式软件工程师
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • $.ajax()参数及用法
  • (07)Hive——窗口函数详解
  • (1)无线电失控保护(二)
  • (poj1.2.1)1970(筛选法模拟)
  • (Python) SOAP Web Service (HTTP POST)
  • (Python第六天)文件处理
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (附源码)计算机毕业设计SSM智能化管理的仓库管理
  • (六)Flink 窗口计算
  • (三) prometheus + grafana + alertmanager 配置Redis监控
  • (十八)三元表达式和列表解析
  • (十六)视图变换 正交投影 透视投影
  • (图文详解)小程序AppID申请以及在Hbuilderx中运行
  • (一)SvelteKit教程:hello world
  • .NET BackgroundWorker