一、字符串

1、字符串截取

  • 可以使用len(字符串变量)获取字符串的字节长度,其中英文占1个字节长度,中文占用3个字节长度

  • 可以使用变量名[n]获取到字符串第n+1个字节,返回这个字节对应的Unicode码值(uint8类型),注意n的取值范围是[0,长度)

    1. package main
    2. import "fmt"
    3. func main() {
    4. s := "smallming张"
    5. a := s[0]
    6. fmt.Println(a) // 115
    7. fmt.Printf("%T\n", a) // unit8
    8. b := fmt.Sprintf("%c", a) // string
    9. fmt.Printf("%T\n", b) // s
    10. fmt.Println(b)
    11. }
  • 可以使用变量名[n:m]取出大于等于n小于m的字符序列

    • n和m都可以省略,省略是认为n为0,m为长度减一
    • 因为中文占用三个字节,如果没有把中文完整取出,会出现乱码
    1. func main() {
    2. s := "smallming张"
    3. fmt.Println(len(s)) //12
    4. fmt.Println(s[1:4]) //mal
    5. fmt.Println(s[:4]) //smal
    6. fmt.Println(s[5:11]) //ming�
    7. fmt.Println(s[5:12]) //ming张
    8. }
  • 可以通过把字符串转换为切片获取长度,并获取里面内容,也可以直接使用for循环结合range获取

    1. func main() {
    2. s := "smallming张"
    3. s1 := []rune(s)
    4. fmt.Println(len(s1))
    5. fmt.Println(s1[9])
    6. fmt.Printf("%c", s1[9])
    7. for i, n := range s {
    8. fmt.Println(i, n)
    9. }
    10. }

2、常用函数

  • 在strings包中提供了字符串常用的函数

  • 常用函数整理如下:

    1. func main() {
    2. s := "smallming"
    3. //第一次出现的索引
    4. fmt.Println(strings.Index(s, "l"))
    5. //最后一次出现的索引
    6. fmt.Println(strings.LastIndex(s, "l"))
    7. //是否含有前缀
    8. fmt.Println(strings.HasPrefix(s, "small"))
    9. //是否含有后缀
    10. fmt.Println(strings.HasSuffix(s, "ming"))
    11. //是否包含
    12. fmt.Println(strings.Contains(s, "mi"))
    13. //转换为小写
    14. fmt.Println(strings.ToLower(s))
    15. //转换为大写
    16. fmt.Println(strings.ToUpper(s))
    17. //替换字符,把字符串中前n个old子字符串替换成new字符串,如果n小于0表示全部替换
    18. fmt.Println(strings.Replace(s, "m", "k", -1))
    19. }

二、常量

1、概述

  • 常量是一个固定值,在编译期间就确定结果,声明时必须赋值且结果不可以改变
  • 因为常量在编译期间就确定,可以防止程序运行过程中意外修改
  • 常量关键字const
  • 常量定义后可以不使用
  • Go语言中常量定义没有明确语法要求,驼峰即可
  • 很多内容都可以定义成常量
    • 人名
    • 圆周率
    • 电话号

2、常量定义

  • 定义常量时如果不是必须指定特定类型,可以省略类型,使用默认类型,且数值类型常量(不定义类型)可以直接进行运算

  • 常量的值可以是表达式,但是不允许出现变量

    1. func main() {
    2. const a string = "smallming"
    3. const b = 123
    4. const c = 3*2 + 5
    5. const d = 1.5
    6. fmt.Printf("%T %T\n", c, d) //int float64
    7. fmt.Println(c + d) //12.5
    8. //下面方式是错误的
    9. i := 3
    10. const e = i*3 + 2
    11. }
  • 当定义多个常量时官方推荐的方式

    1. // 定义常量组
    2. const (
    3. a = 1
    4. b = 2
    5. c = true
    6. )
  • 定义多常量时后一个常量如果没有赋值,与前一个常量值相同

    • 第一个常量必须赋值
    1. func main() {
    2. const (
    3. a = 1
    4. b
    5. c
    6. )
    7. fmt.Println(a, b, c) //1 1 1
    8. }

3、常量生成器

  • 当一组常量都是数值类型,可以使用常量生成器iota指定这组常量按照特定规则变化

  • iota起始值为0,每次增加1

    1. func main() {
    2. const (
    3. a = iota
    4. b
    5. c
    6. )
    7. fmt.Println(a, b, c) //0 1 2
    8. const (
    9. d = iota << 1
    10. e
    11. f
    12. )
    13. fmt.Println(d, e, f) //0 2 4
    14. }
  • 无论是否使用iota,一组常量中每个iota值是固定的,iota按照顺序自增1

  • 每组iota之间无影响

    1. func main() {
    2. const (
    3. a = 5
    4. b = 3
    5. c = iota
    6. d
    7. )
    8. fmt.Println(a, b, c, d) //5 3 2 3
    9. const (
    10. e = iota
    11. f
    12. g = 10
    13. h
    14. i = iota
    15. j
    16. )
    17. fmt.Println(e, f, g, h, i, j) //0 1 10 10 4 5
    18. }

三、指针

1、变量地址

  • 变量本质就是内存中一块数据的标记,把值存储到变量中实质是把值存储到内存中

  • 每次对变量重新赋值就是在修改变量地址中的内容

  • 在Go语言中可以通过&+变量名获取到变量地址值

  • 重新创建一个非引用变量(即使是把已有变量直接赋值给新变量)也会新开辟内存地址

    1. func main() {
    2. a := 3
    3. fmt.Println(&a)
    4. a = 4
    5. fmt.Println(&a)
    6. b := a
    7. b = 5
    8. fmt.Println(&b, &a) //两个值不同
    9. fmt.Println(b, a) //5 4
    10. }

2、指针变量

  • 指针变量指向一个值的内存地址

  • 使用&+变量返回值就是一个指针类型

  • 使用var 变量名 *类型声明指针类型变量

  • 声明指针不会开辟内存地址,只是准备要指向内存某个空间,而声明变量会开辟内存地址,准备存放内容,所以指针类型变量都是把一个变量的地址赋值给指针变量

  • 使用*+指针能够获取内存地址中的值,所以*+指针就和直接使用变量是相同的

  • 应用指针可以实现多个地方操作同一内存地址的值

    1. func main() {
    2. var point *int
    3. fmt.Println(point) //nil
    4. a := 123
    5. point = &a
    6. fmt.Println(point)
    7. *point = 456
    8. fmt.Println(*point, a) //456 456
    9. }

3、空指针

  • 指针目的就是指向内存中一块地址
  • 声明指针后指针不会指向任何内存地址,所以此时指针是空的,在Go语言中空用nil表示

四、new函数

  • 上一节学习了指针,每次创建一个指针必须在额外创建一个变量,操作比较麻烦

  • 可以通过new函数直接创建一个类型的指针

    1. 变量名 := new(type)
  • 使用new函数创建的指针已有指向,可以直接使用*指针对象进行赋值

  • 只声明的指针变量不能直接赋值,只能被赋值为另外一个已初始化的变量地址

    1. func main() {
    2. a := new(int)
    3. fmt.Println(a)
    4. *a = 123
    5. fmt.Println(*a)
    6. var b *int
    7. *b = 345
    8. fmt.Println(*b) //panic: runtime error: invalid memory address or nil pointer dereference
    9. }

五、随机数

  • math/rand实现了伪随机数生成器

  • 在Go语言中随机数需要设置种子,如果不设置种子随机数的结果每次运行都相同

  • 默认种子是1,且相同种子产生的随机数是相同的

  • 可以使用当前时间的纳秒数计算随机数,在一定程度上保证了种子的唯一性

    1. func main() {
    2. fmt.Println(rand.Int63n(10))
    3. fmt.Println(rand.Int63n(6))
    4. fmt.Println(rand.Int63n(5))
    5. rand.Seed(time.Now().UnixNano())
    6. fmt.Println(rand.Int63n(10))
    7. fmt.Println(rand.Int63n(6))
    8. fmt.Println(rand.Int63n(5))
    9. }

六、数组

1、介绍

  • 数组:具有固定长度的相同类型元素序列

  • 声明数组的语法

    1. // var 对象名 [长度]元素类型
    2. var arr [5]int
    3. fmt.Println(arr) // 0 0 0 0 0
  • 数组就是内存中一段固定长度的连续空间

  • 声明数组后数组就会在内存中开辟一块连续空间,每个值称为数组的元素,且元素值为类型对应的默认值,例如int类型默认值为0,string类型默认值为空字符串

  • 数组中每个元素按照顺序都有自己整数类型的脚标,脚标从第一个元素为0向后依次加1

  • 实际开发中数组主要作用是充当临时容器,因为声明一个数组变量比声明多个相同类型变量在操作时更加方便

2、数组的创建和赋值

  • 可以在声明数组时同时给数组赋值,赋值时要求长度必须大于等于初始值个数

    1. func main() {
    2. //完整写法
    3. var arr1 [3]int = [3]int{1, 2, 3}
    4. //短变量方式
    5. arr2 := [3]int{1, 2, 3}
    6. //长度大于初始值个数,长度为4,只给前三个元素赋值,其余元素为默认值
    7. arr3 := [4]int{1, 2, 3}
    8. //赋值时不写长度,数组长度根据元素个数确定
    9. arr4 := [...]int{1, 2, 3}
    10. fmt.Println(arr1, arr2, arr3, arr4)
    11. }
  • 可以通过数组名[脚标]对数组中元素进行操作

  • 通过len(数组变量)获取数组长度,数组脚标最大值为长度减一,如果超出这个范文将会报错

3、数组是值类型

  • 在Go语言中数组是值类型,和之前学习的int或float64等类型相同,把一个数组变量赋值给另一个数组变量时为复制副本,重新开辟一块空间

七、循环

  • 循环:让程序多次执行相同的代码块

  • for循环是Go语言中唯一一个循环结构

  • for循环用的最多的地方就是遍历数组或切片等

    1. func main() {
    2. arr := [2]int{1, 2}
    3. //遍历数组方式1
    4. for i := 0; i < len(arr); i++ {
    5. fmt.Println(arr[i])
    6. }
    7. //遍历数组方式2
    8. //i 脚标
    9. //n 元素内容 n = arr[i]
    10. for i, n := range arr {
    11. fmt.Println(i, n)
    12. }
    13. }
  • 冒泡排序

    1. func main() {
    2. arr := [5]int{1, 7, 6, 3, 2}
    3. for i := 0; i < len(arr)-1; i++ {
    4. for j := 0; j < len(arr)-i-1; j++ {
    5. if arr[j] > arr[j+1] {
    6. arr[j], arr[j+1] = arr[j+1], arr[j]
    7. }
    8. }
    9. }
    10. fmt.Println(arr)
    11. }
  • 循环标签名,多重for循环中,可以定义for标签名

Go语言学习笔记(四)的更多相关文章

  1. Go语言学习笔记四: 运算符

    Go语言学习笔记四: 运算符 这章知识好无聊呀,本来想跨过去,但没准有初学者要学,还是写写吧. 运算符种类 与你预期的一样,Go的特点就是啥都有,爱用哪个用哪个,所以市面上的运算符基本都有. 算术运算 ...

  2. 【GO】GO语言学习笔记四

    流程控制 1.条件语句 举个栗子: if x>5 { return 1; }else{ return 0; } 注意:  条件语句不需要使用括号将条件包含起来(); 无论语句体内有几条语句, ...

  3. Go语言学习笔记(四) [array、slice、map]

    日期:2014年7月22日   一.array[数组]   1.定义:array 由 [n]<type> 定义,n 标示 array 的长度,而 <type> 标示希望存储的内 ...

  4. [C语言学习笔记四]变量与系统的交互

    使用 const 创建常量和使用 volatie 优化变量 C语言中使用 const 定义常量. 例如: const INT a = 10; 此处如果添加a = 20;,编辑器则会报错,因为此处 a ...

  5. HTML语言学习笔记(会更新)

    # HTML语言学习笔记(会更新) 一个html文件是由一系列的元素和标签组成的. 标签: 1.<html></html> 表示该文件为超文本标记语言(HTML)编写的.成对出 ...

  6. C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻

    前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...

  7. IOS学习笔记(四)之UITextField和UITextView控件学习

    IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...

  8. java之jvm学习笔记四(安全管理器)

    java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...

  9. 2017-04-21周C语言学习笔记

    C语言学习笔记:... --------------------------------- C语言学习笔记:学习程度的高低取决于.自学能力的高低.有的时候生活就是这样的.聪明的人有时候需要.用笨的方法 ...

  10. 2017-05-4-C语言学习笔记

    C语言学习笔记... ------------------------------------ Hello C语言:什么是程序:程序是指:完成某件事的既定方式和过程.计算机中的程序是指:为了让计算机执 ...

随机推荐

  1. lamp与zabbix开机自启

    目录 1.控制httpd脚本 2.控制zabbix_server脚本 3.控制zabbix_agentd脚本 4.服务端lamp开机自动启动 5.客户端zabbix_agentd开机自动启动 1.控制 ...

  2. Hibernate第三天-Hibernate主配置信息

    今天是学习Hibernate的第三天,主要分析一下Hibernate的配置文件中的信息 Hibernate中的配置文件有两种,第一种是主配置文件hibernate.cfg.xml,第二种是映射配置文件 ...

  3. python面向对象封装案例2

    封装 封装 是面向对象编程的一大特点 面向对象编程的 第一步 —— 将 属性 和 方法 封装 到一个抽象的 类 中 外界 使用 类 创建 对象,然后 让对象调用方法 对象方法的细节 都被 封装 在 类 ...

  4. ALSA driver--Asoc

    https://blog.csdn.net/zyuanyun/article/details/59170418 ALSA Asoc框架如下图: Asoc分为machine,platform,codec ...

  5. 【C语言】在有序数组中插入一个数,保证它依然有序

    #include<stdio.h> int main() { ] = { ,,,,,, }; int key, i, j; printf("请输入一个数\n"); sc ...

  6. UVA 12124 Assemble(二分答案)

    题目链接:https://vjudge.net/problem/UVA-12124 垃圾vjudge毁我青春!! 首先这道题是解决“最小值最大”的问题,所以要二分答案. 在这里我们二分$quality ...

  7. Unity切换场景后变暗

    这个问题估计很多人都碰到过,原因是切换场景的光照贴图数据丢失,解决方案如下: 打开你要切换的场景,打开Windows-Lighting-Settings,将最下面的Auto Generate前面的勾去 ...

  8. 探讨LoadRunner的并发用户和集合点

    近来跟踪一个项目,发现同事们在执行性能测试时,比较热衷于使用集合点,从概念上认为要得到并发用户就必须设置集合点,认为在执行一个压力测试脚本时,设置了集合点才算是有效的并发用户,没有设置结合点,就认为可 ...

  9. Python(二) isinstance

    原文链接: http://www.baike.com/wiki/isinstance&prd=jinshan https://www.liaoxuefeng.com/wiki/00143160 ...

  10. 剑指offer系列——62.二叉搜索树的第k个结点

    Q:给定一棵二叉搜索树,请找出其中的第k小的结点.例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4. T: 中序遍历,递归: int count = 0; public ...