Go语言学习笔记(四)
一、字符串
1、字符串截取
可以使用len(字符串变量)获取字符串的字节长度,其中英文占1个字节长度,中文占用3个字节长度
可以使用变量名[n]获取到字符串第n+1个字节,返回这个字节对应的Unicode码值(uint8类型),注意n的取值范围是[0,长度)
package main
import "fmt"
func main() {
s := "smallming张"
a := s[0]
fmt.Println(a) // 115
fmt.Printf("%T\n", a) // unit8
b := fmt.Sprintf("%c", a) // string
fmt.Printf("%T\n", b) // s
fmt.Println(b)
}
可以使用变量名[n:m]取出大于等于n小于m的字符序列
- n和m都可以省略,省略是认为n为0,m为长度减一
- 因为中文占用三个字节,如果没有把中文完整取出,会出现乱码
func main() {
s := "smallming张"
fmt.Println(len(s)) //12
fmt.Println(s[1:4]) //mal
fmt.Println(s[:4]) //smal
fmt.Println(s[5:11]) //ming�
fmt.Println(s[5:12]) //ming张
}
可以通过把字符串转换为切片获取长度,并获取里面内容,也可以直接使用for循环结合range获取
func main() {
s := "smallming张"
s1 := []rune(s)
fmt.Println(len(s1))
fmt.Println(s1[9])
fmt.Printf("%c", s1[9])
for i, n := range s {
fmt.Println(i, n)
}
}
2、常用函数
在strings包中提供了字符串常用的函数
常用函数整理如下:
func main() {
s := "smallming"
//第一次出现的索引
fmt.Println(strings.Index(s, "l"))
//最后一次出现的索引
fmt.Println(strings.LastIndex(s, "l"))
//是否含有前缀
fmt.Println(strings.HasPrefix(s, "small"))
//是否含有后缀
fmt.Println(strings.HasSuffix(s, "ming"))
//是否包含
fmt.Println(strings.Contains(s, "mi"))
//转换为小写
fmt.Println(strings.ToLower(s))
//转换为大写
fmt.Println(strings.ToUpper(s))
//替换字符,把字符串中前n个old子字符串替换成new字符串,如果n小于0表示全部替换
fmt.Println(strings.Replace(s, "m", "k", -1))
}
二、常量
1、概述
- 常量是一个固定值,在编译期间就确定结果,声明时必须赋值且结果不可以改变
- 因为常量在编译期间就确定,可以防止程序运行过程中意外修改
- 常量关键字const
- 常量定义后可以不使用
- Go语言中常量定义没有明确语法要求,驼峰即可
- 很多内容都可以定义成常量
- 人名
- 圆周率
- 电话号
2、常量定义
定义常量时如果不是必须指定特定类型,可以省略类型,使用默认类型,且数值类型常量(不定义类型)可以直接进行运算
常量的值可以是表达式,但是不允许出现变量
func main() {
const a string = "smallming"
const b = 123
const c = 3*2 + 5
const d = 1.5
fmt.Printf("%T %T\n", c, d) //int float64
fmt.Println(c + d) //12.5
//下面方式是错误的
i := 3
const e = i*3 + 2
}
当定义多个常量时官方推荐的方式
// 定义常量组
const (
a = 1
b = 2
c = true
)
定义多常量时后一个常量如果没有赋值,与前一个常量值相同
- 第一个常量必须赋值
func main() {
const (
a = 1
b
c
)
fmt.Println(a, b, c) //1 1 1
}
3、常量生成器
当一组常量都是数值类型,可以使用常量生成器iota指定这组常量按照特定规则变化
iota起始值为0,每次增加1
func main() {
const (
a = iota
b
c
)
fmt.Println(a, b, c) //0 1 2
const (
d = iota << 1
e
f
)
fmt.Println(d, e, f) //0 2 4
}
无论是否使用iota,一组常量中每个iota值是固定的,iota按照顺序自增1
每组iota之间无影响
func main() {
const (
a = 5
b = 3
c = iota
d
)
fmt.Println(a, b, c, d) //5 3 2 3
const (
e = iota
f
g = 10
h
i = iota
j
)
fmt.Println(e, f, g, h, i, j) //0 1 10 10 4 5
}
三、指针
1、变量地址
变量本质就是内存中一块数据的标记,把值存储到变量中实质是把值存储到内存中
每次对变量重新赋值就是在修改变量地址中的内容
在Go语言中可以通过&+变量名获取到变量地址值
重新创建一个非引用变量(即使是把已有变量直接赋值给新变量)也会新开辟内存地址
func main() {
a := 3
fmt.Println(&a)
a = 4
fmt.Println(&a)
b := a
b = 5
fmt.Println(&b, &a) //两个值不同
fmt.Println(b, a) //5 4
}
2、指针变量
指针变量指向一个值的内存地址
使用
&+变量
返回值就是一个指针类型使用
var 变量名 *类型
声明指针类型变量声明指针不会开辟内存地址,只是准备要指向内存某个空间,而声明变量会开辟内存地址,准备存放内容,所以指针类型变量都是把一个变量的地址赋值给指针变量
使用
*+指针
能够获取内存地址中的值,所以*+指针
就和直接使用变量是相同的应用指针可以实现多个地方操作同一内存地址的值
func main() {
var point *int
fmt.Println(point) //nil
a := 123
point = &a
fmt.Println(point)
*point = 456
fmt.Println(*point, a) //456 456
}
3、空指针
- 指针目的就是指向内存中一块地址
- 声明指针后指针不会指向任何内存地址,所以此时指针是空的,在Go语言中空用nil表示
四、new函数
上一节学习了指针,每次创建一个指针必须在额外创建一个变量,操作比较麻烦
可以通过new函数直接创建一个类型的指针
变量名 := new(type)
使用new函数创建的指针已有指向,可以直接使用
*指针对象
进行赋值只声明的指针变量不能直接赋值,只能被赋值为另外一个已初始化的变量地址
func main() {
a := new(int)
fmt.Println(a)
*a = 123
fmt.Println(*a)
var b *int
*b = 345
fmt.Println(*b) //panic: runtime error: invalid memory address or nil pointer dereference
}
五、随机数
math/rand实现了伪随机数生成器
在Go语言中随机数需要设置种子,如果不设置种子随机数的结果每次运行都相同
默认种子是1,且相同种子产生的随机数是相同的
可以使用当前时间的纳秒数计算随机数,在一定程度上保证了种子的唯一性
func main() {
fmt.Println(rand.Int63n(10))
fmt.Println(rand.Int63n(6))
fmt.Println(rand.Int63n(5))
rand.Seed(time.Now().UnixNano())
fmt.Println(rand.Int63n(10))
fmt.Println(rand.Int63n(6))
fmt.Println(rand.Int63n(5))
}
六、数组
1、介绍
数组:具有固定长度的相同类型元素序列
声明数组的语法
// var 对象名 [长度]元素类型
var arr [5]int
fmt.Println(arr) // 0 0 0 0 0
数组就是内存中一段固定长度的连续空间
声明数组后数组就会在内存中开辟一块连续空间,每个值称为数组的元素,且元素值为类型对应的默认值,例如int类型默认值为0,string类型默认值为空字符串
数组中每个元素按照顺序都有自己整数类型的脚标,脚标从第一个元素为0向后依次加1
实际开发中数组主要作用是充当临时容器,因为声明一个数组变量比声明多个相同类型变量在操作时更加方便
2、数组的创建和赋值
可以在声明数组时同时给数组赋值,赋值时要求长度必须大于等于初始值个数
func main() {
//完整写法
var arr1 [3]int = [3]int{1, 2, 3}
//短变量方式
arr2 := [3]int{1, 2, 3}
//长度大于初始值个数,长度为4,只给前三个元素赋值,其余元素为默认值
arr3 := [4]int{1, 2, 3}
//赋值时不写长度,数组长度根据元素个数确定
arr4 := [...]int{1, 2, 3}
fmt.Println(arr1, arr2, arr3, arr4)
}
可以通过数组名[脚标]对数组中元素进行操作
通过len(数组变量)获取数组长度,数组脚标最大值为长度减一,如果超出这个范文将会报错
3、数组是值类型
- 在Go语言中数组是值类型,和之前学习的int或float64等类型相同,把一个数组变量赋值给另一个数组变量时为复制副本,重新开辟一块空间
七、循环
循环:让程序多次执行相同的代码块
for循环是Go语言中唯一一个循环结构
for循环用的最多的地方就是遍历数组或切片等
func main() {
arr := [2]int{1, 2}
//遍历数组方式1
for i := 0; i < len(arr); i++ {
fmt.Println(arr[i])
}
//遍历数组方式2
//i 脚标
//n 元素内容 n = arr[i]
for i, n := range arr {
fmt.Println(i, n)
}
}
冒泡排序
func main() {
arr := [5]int{1, 7, 6, 3, 2}
for i := 0; i < len(arr)-1; i++ {
for j := 0; j < len(arr)-i-1; j++ {
if arr[j] > arr[j+1] {
arr[j], arr[j+1] = arr[j+1], arr[j]
}
}
}
fmt.Println(arr)
}
循环标签名,多重for循环中,可以定义for标签名
Go语言学习笔记(四)的更多相关文章
- Go语言学习笔记四: 运算符
Go语言学习笔记四: 运算符 这章知识好无聊呀,本来想跨过去,但没准有初学者要学,还是写写吧. 运算符种类 与你预期的一样,Go的特点就是啥都有,爱用哪个用哪个,所以市面上的运算符基本都有. 算术运算 ...
- 【GO】GO语言学习笔记四
流程控制 1.条件语句 举个栗子: if x>5 { return 1; }else{ return 0; } 注意: 条件语句不需要使用括号将条件包含起来(); 无论语句体内有几条语句, ...
- Go语言学习笔记(四) [array、slice、map]
日期:2014年7月22日 一.array[数组] 1.定义:array 由 [n]<type> 定义,n 标示 array 的长度,而 <type> 标示希望存储的内 ...
- [C语言学习笔记四]变量与系统的交互
使用 const 创建常量和使用 volatie 优化变量 C语言中使用 const 定义常量. 例如: const INT a = 10; 此处如果添加a = 20;,编辑器则会报错,因为此处 a ...
- HTML语言学习笔记(会更新)
# HTML语言学习笔记(会更新) 一个html文件是由一系列的元素和标签组成的. 标签: 1.<html></html> 表示该文件为超文本标记语言(HTML)编写的.成对出 ...
- C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻
前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...
- IOS学习笔记(四)之UITextField和UITextView控件学习
IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...
- java之jvm学习笔记四(安全管理器)
java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...
- 2017-04-21周C语言学习笔记
C语言学习笔记:... --------------------------------- C语言学习笔记:学习程度的高低取决于.自学能力的高低.有的时候生活就是这样的.聪明的人有时候需要.用笨的方法 ...
- 2017-05-4-C语言学习笔记
C语言学习笔记... ------------------------------------ Hello C语言:什么是程序:程序是指:完成某件事的既定方式和过程.计算机中的程序是指:为了让计算机执 ...
随机推荐
- lamp与zabbix开机自启
目录 1.控制httpd脚本 2.控制zabbix_server脚本 3.控制zabbix_agentd脚本 4.服务端lamp开机自动启动 5.客户端zabbix_agentd开机自动启动 1.控制 ...
- Hibernate第三天-Hibernate主配置信息
今天是学习Hibernate的第三天,主要分析一下Hibernate的配置文件中的信息 Hibernate中的配置文件有两种,第一种是主配置文件hibernate.cfg.xml,第二种是映射配置文件 ...
- python面向对象封装案例2
封装 封装 是面向对象编程的一大特点 面向对象编程的 第一步 —— 将 属性 和 方法 封装 到一个抽象的 类 中 外界 使用 类 创建 对象,然后 让对象调用方法 对象方法的细节 都被 封装 在 类 ...
- ALSA driver--Asoc
https://blog.csdn.net/zyuanyun/article/details/59170418 ALSA Asoc框架如下图: Asoc分为machine,platform,codec ...
- 【C语言】在有序数组中插入一个数,保证它依然有序
#include<stdio.h> int main() { ] = { ,,,,,, }; int key, i, j; printf("请输入一个数\n"); sc ...
- UVA 12124 Assemble(二分答案)
题目链接:https://vjudge.net/problem/UVA-12124 垃圾vjudge毁我青春!! 首先这道题是解决“最小值最大”的问题,所以要二分答案. 在这里我们二分$quality ...
- Unity切换场景后变暗
这个问题估计很多人都碰到过,原因是切换场景的光照贴图数据丢失,解决方案如下: 打开你要切换的场景,打开Windows-Lighting-Settings,将最下面的Auto Generate前面的勾去 ...
- 探讨LoadRunner的并发用户和集合点
近来跟踪一个项目,发现同事们在执行性能测试时,比较热衷于使用集合点,从概念上认为要得到并发用户就必须设置集合点,认为在执行一个压力测试脚本时,设置了集合点才算是有效的并发用户,没有设置结合点,就认为可 ...
- Python(二) isinstance
原文链接: http://www.baike.com/wiki/isinstance&prd=jinshan https://www.liaoxuefeng.com/wiki/00143160 ...
- 剑指offer系列——62.二叉搜索树的第k个结点
Q:给定一棵二叉搜索树,请找出其中的第k小的结点.例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4. T: 中序遍历,递归: int count = 0; public ...