Golang易错知识点汇总

目录
  • 类型转换和类型断言
    • 1.类型转换示例代码
    • 2.类型断言代码示例
  • 全局变量
    • 全局变量使用var,编译通过
    • 全局变量不使用var,编译不通过
  • init函数
  • Go接口总结
  • Go字符串
    • 如何修改字符串的内容
  • slice
    • 1.删除单个元素
    • 2.删除多个元素
  • 总结

类型转换和类型断言

类型转换语法:Type(expression)

类型断言语法为:expression.(Type)

1.类型转换示例代码

package main

import "fmt"

//典型的类型转换示例
func main() {
   // 类型转换示例
   var a int = 5
   var b int = 2
   var c float32
   c = float32(a) / float32(b) //这里就是典型的类型转换
   fmt.Printf("a的类型:%T\n", a)
   fmt.Printf("b的类型:%T\n", b)
   fmt.Printf("c的类型:%T\n", c)
   fmt.Printf("c的值:%v\n", c)
   //如果我们不进行类型转换,看下输出结果
   fmt.Printf("不进行类型转换的输出结果:%v\n", a/b) //从结果可以看出值为2,丢失了精度
}

打印结果

2.类型断言代码示例

注意:对于类型断言,expression 必须是接口类型

package main

import "fmt"

//经典的类型断言示例 搭配switch使用
func main() {
   var x interface{}
   x = 1
   switch x.(type) { //这就是上面说的expression.(Type)
   case float32:
      fmt.Println("类型是:float32")
   case string:
      fmt.Println("类型是:string")
   case int:
      fmt.Println("类型是:int")
   default:
      fmt.Println("未知类型")
   }
}

运行结果

全局变量

定义全局变量必须用var,全局变量要定义在函数之外,而在函数之外定义的变量只能用var定义。

全局变量使用var,编译通过

全局变量不使用var,编译不通过

init函数

这是官方对于init()函数的介绍:

变量除了可以在全局声明中初始化,也可以在 init ()函数中初始化。这是一类非常特殊的函数,它不能够被人为调用,而是在每个包完成初始化后自动执行,并且执行优先级比 main 函数高。 初始化总是以单线程执行,并且按照包的依赖关系顺序执行。 一个可能的用途是在开始执行程序之前对数据进行检验或修复,以保证程序状态的正确性。

如何觉得上面这一大段话不好理解的话,可以看我的总结:

  • init函数可以在任何包中有0个、1个或多个;
  • main函数只能在main包中有且只有一个,但是main包中也可以有0个、1个或多个init函数;
  • init函数和main函数都不能被显式调用;

Go语言中变量、init函数、main函数的执行顺序

  • 首先初始化导入包的变量和常量
  • 然后执行导入包的init函数
  • 然后初始化本包的变量和常量
  • 然后执行本包的init函数
  • 最后执行本包的main函数

Go接口总结

这是我在刷题的时候碰到的,总结出来给大家:

  • 如果两个接口拥有相同方法列表(顺序可以不一致),那么这两个接口实质上同一个接口
  • 接口A是接口B的子集,意味着A的方法B中都有,那么A是B的基类,所以A=B是可行的
  • 接口是否能够调用成功,需要运行的时候才能知道
  • 接口赋值是否可行,在编译阶段就可以知道

Go字符串

Go语言中的字符串不支持下标操作

在go语言中,字符串是一种基本类型,和其它开发语言不同,Go的字符串是由单个字节连接起来的。

Go语言统一使用utf-8编码标识Unicode文本。当字符为ASCII编码时,占用1个字节,其它字符占用2到4个字节,中文占用3个字节

如何修改字符串的内容

有三种方法:

  • 将字符串转成byte切片,再根据下标替换内容
  • 将字符串转为rune切片,再根据下标替换内容
  • 使用原生包 strings 中的 Replace() 方法

示例代码

package main

import (
   "fmt"
   "strings"
)

func main() {
   //第一种方法 将字符串转成byte切片
   s := "hello"
   s2 := []byte(s)
   s2[0] = 'x'
   fmt.Printf("转成byte切片:%v\n", string(s2)) //打印结果:转成byte切片:xello

   // 第二种方法 将字符串转为rune切片
   s3 := "王中阳"
   s4 := []rune(s3) //注意:中文字符串要进行修改,只能转成rune切片,不能转成byte切片
   s4[0] = '杨'
   fmt.Printf("转成rune切片:%v\n", string(s4)) //打印结果:转成rune切片:杨中阳

   // 第三种方法,使用原生包strings 中的 Replace() 方法
   s5 := "abcdef"
   old := "abc"
   newString := "ABC"
   s6 := strings.Replace(s5, old, newString, -1) //最后一个参数n的作用是:返回将s5中前n个不重叠old子串都替换为new的新字符串,如果n<0会替换所有old子串。
   fmt.Printf("strings替换之后的:%v\n", s6)           //打印结果:strings替换之后的:ABCdef
}

运行结果

slice

slice可以通过append方式实现元素的删除。

**切片使用冒号分隔时遵循"前闭后开"原则,即包括前面的值,不包括后面的值。 **

1.删除单个元素

package main

import "fmt"

//使用append 删除单个元素
func main() {
   var data = []int{0, 1, 2, 3, 4, 5}
   //删除元素2
   index := 2
   //切片使用冒号分隔时遵循"前闭后开"原则,即包括前面的值,不包括后面的值。
   data1 := append(data[:index], data[index+1:]...)
   fmt.Println(data1)
}

运行结果

2.删除多个元素

package main

import "fmt"

//使用append 删除多个元素
func main() {
   var data = []int{0, 1, 2, 3, 4, 5}
   //删除元素0,1,2
   index := 2
   //切片使用冒号分隔时遵循"前闭后开"原则,即包括前面的值,不包括后面的值。
   data1 := append(data[:0], data[index+1:]...)
   fmt.Println(data1)
}

运行结果

总结

这篇文章汇总了我再开发和刷面试题过程中遇到的容易搞错的知识点,包括:

  • 类型转换和类型断言的对比
  • 定义全局变量只能用var,定义全局变量也可以定义在init()函数中
  • init()函数的知识点,以及init函数和main函数的执行顺序:先执行引用包的常量和变量、在执行引用包的init函数、再执行本包的常量和变量、再执行本包的init函数、最后才会执行本包的main函数。
  • Go接口的概念总结,刷面试题的时候可能碰到咬文嚼字的问题,注意避坑。
  • Go字符串不能通过下标直接修改内容,但是可以通过转成byte[]/rune[]/以及使用原生包strings中的Replace()方法修改内容
  • Go中的slice不能像map一样直接使用delete()方法删除元素,可以使用append()方法+冒号分隔切片的方式,间接实现切片元素的删除。

到此这篇关于Golang易错知识点汇总的文章就介绍到这了,更多相关Golang知识点内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 解决golang 关于全局变量的坑

    学习golang不久,在定义全局变量的时候遇见了坑.写个小例子,增强记忆. 错误版本 var p int func main() { p, err := test(4) if err != nil { log.Fatal(err) } } func test(i int) (int, error) { return i + 1, nil } 编译一直不通过,p declared and not used.后来查了查资料,看见这种其实是在main里边又重新定义了p,所以一直提示p定义了但是没有使用

  • go语言 全局变量和局部变量实例

    一.局部变量 1 定义在{}里面的变量时局部变量,只能在{}里面有效 2 执行到定义的那句话,开始分配内存空间,离开作用域自动进行释放 3 作用域,就是变量作用的范围 package main import "fmt" func test() { i := 111 fmt.Println("i=", i) } func main() { test() { i := 10 fmt.Printf("i=%v\n", i) } // i=12 错误 i

  • GO语言类型查询类型断言示例解析

    目录 类型查询 1.comma-ok断言 2. switch测试 类型断言 类型查询 我们知道interface的变量里面可以存储任意类型的数值(该类型实现了interface).那么我们怎么反向知道这个变量里面实际保存了的是哪个类型的对象呢?目前常用的有两种方法: comma-ok断言 switch测试 1.comma-ok断言 Go语言里面有一个语法,可以直接判断是否是该类型的变量: value, ok = element.(T),这里value就是变量的值,ok是一个bool类型,elem

  • 详解Go语言中的数据类型及类型转换

    目录 1.基本数据类型 2.基础数据类型转换 3.基本数据类型转为字符串 4.strconv的使用 5.字符串转为基础类型 1.基本数据类型 数据类型有很多,先研究一下基础的,例如:布尔型.数字类型.字符串类型. 数字类型有uint8.uint16.uint32.uint64.int8.int16.int32.int64(uint和int区别在于uint为无符号整数,即只支持正数,不支持负数形式) 数字浮点型有fload32.float64.complex64.complex126(后面两个均为

  • golang类型推断与隐式类型转换

    目录 前言 一.常量的隐式类型转换 1.常量的声明 2.常量的类型转换 3.隐式转换的原理 二.变量的类型推断 1.类型推断的原理 三.类型推断示例分析 总结 前言 golang类型推断可以省略类型,像写动态语言代码一样,让编程变得更加简单,同时也保留了静态类型的安全性. 类型推断往往也伴随着类型的隐式转换,二者均与golang的编译器有关.在了解了golang的类型推断与隐式类型转换原理后,将对如下问题信手拈来——下述代码能通过编译吗?b的值是什么类型? // eg.1 a := 1.1 b

  • golang的强制类型转换实现

    golang是一种强类型语言,虽然在代码中经常看到这种写法,i:=10这其实这是编译器自动做了类型推断在编译期间.编译器会对数据进行类型检查.不同类型的数据不能赋值,不能在函数中传参.强类型语言有一些优势,很多的错误会在编译期间被检查出来,不想php和python等弱类型语言,很多错误只有运行到才能被发现.同样,强类型也有一些缺点,写代码的时候要考虑数据类型了,失去了一些灵活性. 言归正传,开始golang的类型转换问题 golang的类型转换和C/C++ java等语言的类型转换还有点区别 C

  • Golang易错知识点汇总

    目录 类型转换和类型断言 1.类型转换示例代码 2.类型断言代码示例 全局变量 全局变量使用var,编译通过 全局变量不使用var,编译不通过 init函数 Go接口总结 Go字符串 如何修改字符串的内容 slice 1.删除单个元素 2.删除多个元素 总结 类型转换和类型断言 类型转换语法:Type(expression) 类型断言语法为:expression.(Type) 1.类型转换示例代码 package main import "fmt" //典型的类型转换示例 func m

  • Java正则表达式易错知识点汇总

    一.概述 正则表达式是Java处理字符串.文本的重要工具. Java对正则表达式的处理集中在以下两个类: java.util.regex.Matcher   模式类:用来表示一个编译过的正则表达式. java.util.regex.Pattern   匹配类:用模式匹配一个字符串所表达的抽象结果. (很遗憾,Java Doc并没有给出这两个类的职责概念.)  比如一个简单例子: import java.util.regex.Matcher; import java.util.regex.Patt

  • javascript 易错知识点实例小结

    本文实例总结了javascript 易错知识点.分享给大家供大家参考,具体如下: 为什么 typeof null === 'object' 原理是这样的,不同的对象在底层都表示为二进制,在JavaScript中二进制前三位都为0的话会被判断为 object 类型, null 的二进制表示是全0,自然前三位也是0,所以执行 typeof 时会返回" object ". 对象属性的存在性 如 myObject.a 的属性访问返回值可能是 undefined ,但是这个值有可能是属性中存储的

  • JavaScript易错知识点整理

    前言 本文是我学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,类型比较,this指向,函数参数,闭包问题及对象拷贝与赋值这6个方面进行由浅入深的介绍和讲解,其中也涉及了一些ES6的知识点. JavaScript知识点 1.变量作用域 var a = 1; function test() { var a = 2; console.log(a); // 2 } test(); 上方的函数作用域中声明并赋值了a,且在console之上,所以遵循就近原则输出a等于2. va

  • Pandas-DataFrame知识点汇总

    目录 1.DataFrame的创建 根据字典创建 读取文件 2.DataFrame轴的概念 3.DataFrame一些性质 索引.切片 修改数据 重新索引 丢弃指定轴上的值 算术运算 函数应用和映射 排序和排名 汇总和计算描述统计 处理缺失数据 1.DataFrame的创建 DataFrame是一种表格型数据结构,它含有一组有序的列,每列可以是不同的值.DataFrame既有行索引,也有列索引,它可以看作是由Series组成的字典,不过这些Series公用一个索引.DataFrame的创建有多种

  • C/C++常用函数易错点分析

    本文简单分析了C/C++中常用函数的易错点,包括memset.sizeof.getchar等函数.分享给大家供大家参考之用.具体分析如下: 1.memset #include <string.h> void* memset( void* buffer, int ch, size_t count ); 将内存中buffer的前count个字节的内容全部设置为ch指定的ASCII值.经常用来初始化数组.复制时以字节为单位,如果buffer是int long,或者其他类型的指针时,需要注意不一定为数

  • 总结js中的一些兼容性易错的问题

    一.属性相关 我们通常把特征(attribute)和属性(property)统称为属性,但是他们确实是不同的概念, 特征(attribute)会表现在HTML文本中,对特征的修改一定会表现在元素的outerHTML中,并且特征只存在于元素节点中: 属性(property)是对于JS对象进行修改,除了浏览器内置的部分特征外,其它的属性操作并不会影响HTML文本. 1. IE6/7不区分属性和特征 其它浏览器会区分属性和特征,而IE67并不会区分它们,在IE67下我们只能用属性名来删除特征,虽然这两

  • Android悬浮窗的实现(易错点)

    0. 前言 现在很多应用都使用到悬浮窗,例如微信在视频的时候,点击Home键,视频小窗口仍然会在屏幕上显示.这个功能在很多情况下都非常有用.那么今天我们就来实现一下Android悬浮窗,以及探索一下实现悬浮窗时的易错点. 1. 实现原理 1.1 悬浮窗插入接口 在实现悬浮窗之前,我们需要知道通过什么接口,能够将一个控件放入到屏幕中去. Android的界面绘制,都是通过WindowMananger的服务来实现的.那么,既然要实现一个能够在自身应用以外的界面上的悬浮窗,我们就要利用WindowMa

  • SpringBoot整合Mybatis的知识点汇总

    springboots使用的版本是2.0.1,注意不同版本可能有差异,并不一定通用 添加Mybatis的起步依赖: <!--mybatis起步依赖--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.1.1</version&

  • python闭包、深浅拷贝、垃圾回收、with语句知识点汇总

    1.1 闭包 1.闭包概念 1. 在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用,这样就构成了一个闭包 2. 一般情况下,在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失. 3. 但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束. 2.闭包特点 1. 必须有一个内嵌函数 2. 内嵌函数必须引用外部函数中的变量 3.

随机推荐