声明和初始化 Mapmap 是一种特殊的数据结构,通过键 key 和值 value 来保存数据,可以快速地根据 key 找到其对应的 value,与 python 中的字典和 Java 中的 HashMap 类似。
map 是引用类型,声明方式如下:
1var variable map[keyType]valueType
在声明的时候不需要知道 map 的长度,map 是可以动态增长的。
未初始化的 map 的值是 nil。
map 中的 key 只能是可以用 == 和 != 来比较的变量类型,例如 string,int 和 float 等,不能是数组,结构体和切片,但指针和接口可以作为 key。如果要使用结构体来作为 key,需要提供 Key() 和 Hash() 方法,value 可以为任意类型。
可以通过赋值符号来设置 key1 对应的 value:
1map1[key1] = value
也可以根据赋值符号获取 key1 对应的 value,若 map1 中没有 key1 对应的值,val 将会被赋值 map1 的值类型的空值。
1val := map1[key1]
示例 ...
Go 语言通过 定义结构体来支持用户自定义类型。一个结构体代表现实世界中的一个实体,类似于 Java 中的实体类。当要定义一个类型时,这个类型包含很多属性,例如定义一个用户类型,用户类型中包含用户名、密码和生日等属性,就可以使用结构体。
组成结构体属性的数据成为字段,每个字段都有类型和名称;在结构体中,字段名称必须唯一。由于 Go 语言中不存在类的概念,所以结构体 struct 在 Go 语言中有着较高的地位。
结构体的定义格式结构体定义的格式如下:
1234type variable struct { field1 type1 field2 type2}
若结构体中有多个同类型字段,可以简写,如:
123type T struct { a, b int}
若结构体中的字段并不需要使用,可以用匿名变量 _ 来定义,如:
123type M struct { _ int}
结构体中字段的类型可以是任意类型(包括结构体、函数和接口等)。
使用 new可以使用 new 函数给新结构体变量分配内存,它返回 ...
反射是用程序检查其所拥有的结构,尤其是类型的一种能力。反射可以在运行时(不必在编译时)检查类型和变量,例如大小、变量、方法和动态调用这些方法。
方法和类型的反射reflect 包提供了反射功能,它定义两个重要类型:Type 和 Value,分别表示动态类型和值。
有两个常用的方法:
reflect.TypeOf:返回对象的具体类型。
reflect.ValueOf:返回对象的值。
反射是先检查一个接口的值,再将变量转换成空接口类型,我们看下这两个函数的定义就能明白了:
12func TypeOf(i interface{}) Typefunc ValueOf(i interface{}) Value
reflect.TypeOf函数 reflect.Typeof() 可以接收任意 interface{} 类型数据,并返回其动态类型。
123456789101112package mainimport ( "fmt" "reflect")func main() { t := reflect. ...
1. 使用接口的原因我们来看一段代码:
1234567891011121314type Cat struct{}func (c Cat) Say() string { return "喵喵喵" }type Dog struct{}func (d Dog) Say() string { return "汪汪汪" }func main() { c := Cat{} fmt.Println("猫:", c.Say()) d := Dog{} fmt.Println("狗:", d.Say())}
上述代码中定义了狗 Dog 和猫 Cat 以及它们对应的方法 Say(),若要继续添加鸭 Duck 方法和其对应的方法 Say(),重复代码会非常多。我们可不可以从这三种动物类型中抽象出方法 Say(),这就是接口的作用,接口可以定义抽象方法,来规范我们的代码。
2. 接口的定义和 ...
传递变长参数如果函数最后一个参数采用 ...type 的形式,那么这个函数就可以处理一个变长参数(长度可以为 0),这样的函数被称为变参函数,如:
1func myFunc(a int, args ...int)
如果参数存储在切片 arr 中,可以用 arr... 来传递参数,如:
123456789101112131415161718192021222324252627package mainimport "fmt"func main() { x := Min(1, 3, 2, 0) fmt.Printf("The minimum is: %d\n", x) arr := []int{7, 9, 3, 5, 1} x = Min(arr...) fmt.Printf("The minimum in the arr is: %d", x)}func Min(a ...int) int { if len(a) == 0 { ...
Go 没有像 Java 那样的 try/catch 异常处理机制,而是用 defer/panic/recover 机制来处理异常。
Go 语言的设计者认为 try/catch 机制使用过于泛滥,而且从底层向高层抛出错误太耗费资源,因此他给 Go 语言设计了一种返回值处理错误方式:通过在函数和方法中返回错误对象,这个错误对象一般在多个返回值的最后;如果返回 nil,则表明没有错误,且主调函数应该检查并处理每一个错误。
我们通过调用 pack1 包中的 Func1 函数来了解 Go 语言中的错误处理方式:
Func1返回了两个值,一个 value和 err,err 是错误对象,若 err 不为 nil(nil 是空的意思,类似于 Java 中的 null),则进行错误处理,打印出具体错误信息。
1234if value, err := pack1.Func1(param1); err != nil { fmt.Printf("Error %s in pack1.Func1 with parameter %v", err.Error(), param1 ...
基本概念线程和进程
进程 :是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个 独立单位 。
线程 :是进程的一个执行实体,是 CPU 调度和分派的 基本单位 ,它是比进程更小的能独立运行的 基本单位 。
一个进程可以创建或撤销多个线程;同一个进程中的多个线程之间可以并发执行。
线程和协程
协程 :独立栈空间,共享堆空间,调度由用户自己控制,本质上有点类似于用户级线程,这些用户级线程的调度也是自己实现的。
线程 :一个线程上可以跑多个协程,协程是轻量级的线程。
并发和并行并发 和 并行 虽然相似,但是有所不同:
并发 :逻辑上具备同时处理多个任务的能力。
并行 :物理上在同一时刻执行多个并发任务。
我们一般会说程序是并发的,意思是说它允许多个任务同时进行,但不一定在同一时刻发生。对于单核处理器,它们能以间隔方式切换运行;而并行则依赖多核心处理器,是让多个任务真正能在同一时刻运行,是一种程序运行的状态。
多线程和多进程是并行的基本条件,但单线程也可用协程(coroutine)做到并发。虽然单线程只能通过主动切换来实现并发,但也有优点,可以避免由于切换线程导致的资源消耗 ...
名称
示例
实质重于形式
(1)金融负债与权益工具的区分。(2)合并财务报表合并范围的确定。(3)附有追索权的票据贴现。(4)控股股东代为偿债、债务豁免等
重要性
无论会计差错重要与否均需进行调整:(1)重要的会计差错:追溯重述。(2)不重要的会计差错:无须追溯重述
相关性
(1)区分收入和利得、费用和损失。(2)区分流动资产和非流动资产、流动负债和非流动负债。(3)以及适度引入公允价值等
谨慎性
(1)各类资产计提减值准备。(2)确实无法区分研究阶段的支出和开发阶段的支出,应将其所发生的研发支出全部费用化,计入当期损益。(3)递延所得税资产的确认应以未来可以取得的应纳税所得额为限。(4)企业在销售商品时便根据历史经验对承担的保修义务确认预计负债等
前言从第一次接触 vim 已逾期 10 年, 期间大部分都是一些简单操作,最近一两年开始深度使用 vim, 目前使用 neovim 版本.本文将记录一些笔者觉得好用的一些 Plugin, 本文也将持续更新.
注意: 笔者使用的插件管理器是 vim-plug,所以以下示例都是基于 vim-plug 来写的.
Goto/Openvim-open-urlvim-open-url可以用浏览器打开光标下的 url.
gB 用默认浏览器打开光标下的 url
g<CR> 使用默认搜索引擎搜索光标下的单词
gG 使用 Google 搜索光标下的单词
gW 使用 Wikipedia 搜索光标下的单词
1Plug 'dhruvasagar/vim-open-url'
Auto Completeneoclide/coc.nvim

