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

阳春县建设局网站xiaohua wordpress主题

阳春县建设局网站,xiaohua wordpress主题,装饰设计网站,太原工程建设信息网站文章目录 数组切片append 函数copy 函数删除元素 映射delete 函数 函数init 特殊的函数defer 语句panic / recover 错误处理 类型结构体内存对齐JSON 序列化与反序列化方法和接收者 项目代码地址#xff1a;03-ArraySliceMapFuncStruct 数组 基本格式#xff1a;var 数组变… 文章目录 数组切片append 函数copy 函数删除元素 映射delete 函数 函数init 特殊的函数defer 语句panic / recover 错误处理 类型结构体内存对齐JSON 序列化与反序列化方法和接收者 项目代码地址03-ArraySliceMapFuncStruct 数组 基本格式var 数组变量名 [元素数量]T 数组长度必须是常量或者常量表达式数组大小不可以修改数组不支持负数索引... 自动推导第一维数组长度 // Array 1 func function01() {const lenA 2var a [lenA 1]int // 常量表达式定义数组长度// var lenB 3// b : [lenB]int{} 错误变量不可用于定义数组长度var b [1]bool{true} // 基本初始化var c [2]string [...]string{A, B} // 省略号自行推断数组长度d : [...]int{1: -1, 3: 5} // 索引值初始化fmt.Println(a, b, c, d) // [0 0 0] [true] [A B] [0 -1 0 5]// 第一维可自动推导长度citys : [...][3]string{{北京, 上海, 广州},{重庆, 湖南, 武汉},}fmt.Println(citys) // [[北京 上海 广州] [重庆 湖南 武汉]]// 二维数组遍历for _, v1 : range citys {for _, city : range v1 {fmt.Print(city)}} // 北京上海广州重庆湖南武汉 }数组是值类型赋值和传参会拷贝副本数组同类型可以进行比较 // Array 2 func function02() {a : [...]int{1, 2}b : ab[0] 3fmt.Println(a, b) // [1 2] [3 2]for i, length : 0, len(a); i length; i {fmt.Printf(%v , a[i])} // 1 2fmt.Println()// 同类型且内部元素可比较那么可以使用 和 ! 比较两个数组fmt.Printf(%#v %#v %T %T %t %t\n, a, b, a, b, b a, b ! a) // [2]int{1, 2} [2]int{3, 2} [2]int [2]int false true }切片 基本格式var 切片变量名 []T 切片表达式a[low: high: max]满足 0 low high max cap(a)仅 low 可以省略默认 0 切片不同于数组切片长度不固定可以通过 append 向切片动态添加元素并且会自动扩容。切片是一个引用类型可以基于字符串、数组、切片及其指针通过切片表达式得到切片。 // Slice 1 func function03() {a : [5]int{1, 2, 3, 4: -1} // 1 2 3 0 -1strA : Hello GolangptrStrA : new(string)ptrStrA strAsliceA : a[1:5] // 基于数组sliceStrA : strA[6:] // 基于字符串slicePtrStrA : (*ptrStrA)[:5] // 基于字符串指针fmt.Println(sliceA, sliceStrA, slicePtrStrA) // [2 3 0 -1] Golang HellosliceB : sliceA[2:] // 基于切片fmt.Println(sliceB) // [0 -1]sliceB[0] -2 // 引用类型fmt.Println(a, sliceA, sliceB) // [1 2 3 -2 -1] [2 3 -2 -1] [-2 -1] }切片表达式第三维 max表示当前截取出的切片的容量 cap max - low。即 low 是起始位置high 是 len 长度的结尾位置后一位左闭右开max 是 cap 容量的结尾位置后一位。 如果想要动态创建切片需要使用内置 make 函数make([]T, size, cap) 使用 make 函数可以一次性将切片所需容量申请到位可以避免小切片的多次动态扩容。 // Slice 2 func function04() {a : [...]int{0, 1, 2, 3, 4, 5, 6, 7}fmt.Println(a, len(a), cap(a)) // [0 1 2 3 4 5 6 7] 8 8sliceA1 : a[1:5]fmt.Println(sliceA1, len(sliceA1), cap(sliceA1)) // [1 2 3 4] 4 7sliceA2 : a[1:5:7]fmt.Println(sliceA2, len(sliceA2), cap(sliceA2)) // [1 2 3 4] 4 6b : make([]int, 1, 4)b append(b, 2, 3)fmt.Println(b) // [0 2 3] }nil 切片和 empty 切片 nil 切片不仅没大小容量且不指向任何底层数组 empty 切片没大小容量但指向一个特殊的内存地址 zerobase — 所有 0 字节分配的基地址 判断一个切片是否为空使用 len(a) 0 而不要直接使用 a nil因为切片元素不是直接存储的值所以也不允许切片之间使用 比较唯一合法可以和 nil 进行比较。 // Slice 3 func function05() {var s1 []int // nil 切片不仅没大小容量且不指向任何底层数组s2 : []int{}s3 : make([]int, 0) // s2、s3 都是 empty 切片没大小容量但指向一个特殊的内存地址 zerobase - 所有 0 字节分配的基地址fmt.Println(len(s1), len(s2), len(s3), cap(s1), cap(s2), cap(s3)) // 0 0 0 0 0 0fmt.Println(s1 nil, s2 nil, s3 nil) // true false falsefmt.Printf(%#v %#v %#v\n, s1, s2, s3) // []int(nil) []int{} []int{}// fmt.Println(s1 s2) // 切片之间不允许直接使用 比较唯一可以和 nil 进行比较 }append 函数 基本格式append(slice []Type, elems ...Type) []Type 切片在使用 append 函数后可能会造成扩容改变底层数组的地址Go 编译器也不允许调用 append 函数后不使用其返回值所以通常使用原变量接收 append 函数的返回值。 可以对 nil 切片直接使用 append可以一次性添加多个元素到末尾 // Slice 4 func function06() {var a []int // nil 切片a append(a, 2, 3, 4)fmt.Println(a, len(a), cap(a)) // [2 3 4] 3 3 }copy 函数 基本格式copy(destSlice, srcSlice []T) int 不希望两个切片共享底层同一个数组可以使用 copy 函数执行深拷贝 // Slice 5 func function07() {a : []int{1, 2, 3}var b make([]int, len(a), len(a))copy(b, a) // 深拷贝fmt.Println(a, b) // [1 2 3] [1 2 3]b[0] -1fmt.Println(a, b) // [1 2 3] [-1 2 3] }删除元素 借助切片本身的特性来删除索引 x 元素append(a[:x], a[x 1:]...)借助 copy 来删除索引 x 元素copy(a[x:], a[x 1:])最终元素需要少一位输出 // Slice 6 func function08() {a : []int{1, 2, 3}b : append(a[:1], a[2:]...)fmt.Println(b) // [1 3]copy(a[1:], a[2:])fmt.Println(a[:len(a)-1]) // [1 3] }映射 基本格式map[KeyType]ValueType Go 中的 map 是引用类型并且必须初始化才能使用不像 nil 切片能直接使用。 // Map 1 func function09() {var a map[string]intb : map[string]int{}c : make(map[string]int)fmt.Println(a nil, b nil, c nil) // true false false }同样使用 make 函数初始化make(map[T]T, cap)第二个参数表示初始化创建的 map 容量大小。 判断键值是否存在val, ok : map[key] key 存在返回 key 对应 val且 ok 为 truekey 不存在返回 值类型零值ok 为 false // Map 2 func function10() {b : map[string]int{周一: 1,周二: 2,}b[周三] 3// 遍历 mapfor k, v : range b {println(k, v)}// 取值第二个返回值表示是否存在该元素if v, ok : b[周二]; ok {fmt.Println(v)} }delete 函数 基本格式delete(m map[Type]Type1, key Type) // Map 3 func function11() {m : make(map[int]string, 4)m[1] Pythonm[2] Gom[3] Luafor _, v : range m {fmt.Println(v)} // Python Go Luadelete(m, 2)for _, v : range m {fmt.Println(v)} // Python Lua }函数 基本格式 func 函数名(参数)(返回值) {函数体 }Go 语言中支持函数、匿名函数和闭包并且函数在 Go 语言中属于“一等公民”。 多返回值 // 多返回值 func function13(a int, b int) (int, int) {return b, a }返回值命名 // 返回值命名 func function12(x, y int) (ret int) {ret x yreturn }变参函数 // 变参函数 func function14(nums ...int) int {sum : 0for _, v : range nums {sum sum v}return sum }变参传递 func function14_1() {ret : function14([]int{1, 2, 3}...)fmt.Print(ret) // 6 }函数参数 // 函数参数 func function15(a, b int, f func(int, int) int) {f(a, b)return }函数变量匿名函数 // 函数变量 func function16() {add : func(a, b int) int {return a b}function15(1, 2, add) }函数返回值函数闭包 // 函数返回值 func function17() func(int) int {y : 1return func(x int) int {return x y} }递归 闭包也可以是递归的但要求在定义闭包之前用类型化的 var 显式声明闭包。 // 递归 func function20() {var dfs func(int) intdfs func(x int) int {if x 3 {return 3}return x dfs(x1)}ret : dfs(1)fmt.Print(ret) // 1233 9 }init 特殊的函数 程序启动时自动执行每个包的 init 函数 func init() {fmt.Println(main init) }defer 语句 Go 语言中的 defer 语句会将其后面跟随的语句进行延迟处理。 在 defer 归属的函数即将返回时将延迟处理的语句按 defer 定义的逆序进行执行也就是说先被 defer 的语句最后被执行最后被 defer 的语句最先被执行。 // defer func function18() {f1 : func() {fmt.Print(1)}f2 : func() {defer f1()fmt.Print(2)}defer func() {fmt.Print(3)defer f2()}() // 321return }Go 函数中 return 语句在底层并不是原子操作它分为给返回值赋值和 RET 指令两步。 而 defer 语句执行的时机就在返回值赋值操作后RET 指令执行前。如下图所示参考 defer 注册要延迟执行的函数时该函数所有的参数都需要确定其值 func calc(index string, a, b int) int {ret : a bfmt.Println(index, a, b, ret)return ret }func function19() {x : 1y : 2defer calc(AA, x, calc(A, x, y))x 10defer calc(BB, x, calc(B, x, y))y 20 }A 1 2 3 B 10 2 12 BB 10 12 22 AA 1 3 4 panic / recover 错误处理 panic 的一种常见用法是当函数返回我们不知道如何处理或不想处理的错误值时中止操作。 recover 可以阻止 panic 中止程序并让它继续执行。 举例 当其中一个客户端连接出现严重错误服务器不希望崩溃。 相反服务器希望关闭该连接并继续为其他的客户端提供服务。 注意 必须在 defer 的函数中调用 recover不可以直接 defer recover()defer 一定要在可能引发 panic 的语句之前定义 // panic, recover func function21() {defer func() {if err : recover(); err ! nil {fmt.Println(recover err:, err)}}() // recover err: function error!func() {panic(function error!)}()fmt.Println(After panic) // 不会执行 }当跳出引发 panic 的函数时defer 会被激活 其中的 recover 会捕获 panic并且 recover 的返回值是在调用 panic 时抛出的错误。 最后一行代码不会执行因为 main 程序的执行在 panic 点停止并在继续处理完 defer 后结束。 类型 类型定义 语法规则type NewType SourceType 类型定义定义了全新类型该类型与源类型底层类型相同。 类型别名 语法规则type TypeAlias Type 类型别名和其源类型本质上同属一个类型。 // 类型定义类型别名 func function22() {type MyInt int // 类型定义var a int 1var b MyIntb MyInt(a) // 必须显示转换fmt.Printf(%T\n, b) // main.MyInttype MyFloat float32 // 类型别名var A float32 0.1var B MyFloatB A // 只是别名本质同属一个类型fmt.Printf(%T\n, B) // float32 }从上述输出结果来看类型定义是表示 main 包下定义的类型 MyInt而类型别名仍然是源类型类型别名只存在源代码中编译时会自动替换为原来的类型。 结构体 基本格式 type 类型名称 struct {字段名称 字段类型 }在声明结构体字段时也可以指定标签 tag形如 key1:value1 key2:value2并且需要用反引号包裹。标签信息可以在程序运行时通过反射机制被读取比如被用于在结构体变量和 JSON 数据之间转换时通过 tag 建立联系。 // 结构体 type Info struct {Email stringPhone string }type Person struct {ID int64 json:id form:id // tag 标签Name stringContact Info }结构体不能包含自己但可以包含它的指针类型 type Node struct {val int next *Node }结构体初始化 func function23() {a : Info{Email: 123163.com,Phone: 123456,}// 结构体简单按顺序初始化b : Info{456163.com,987654,}fmt.Printf(%T %T\n, a, Person{}) // main.Info main.Personfmt.Println(a, b) // {123163.com 123456} {456163.com 987654} }匿名结构体 func function24() {a : struct {x, y int}{1, 2,}fmt.Println(a) // {1 2} }结构体嵌套 func function27() {type Student struct {Name stringInfo // 结构体嵌套}var a Studenta Student{Name: Cauchy,Info: Info{Email: 123163.com,Phone: 123456,},}fmt.Println(a.Name, a.Email, a.Phone) // Cauchy 123163.com 123456 }自定义结构体构造函数 一般结构体较为复杂则可以使用返回指针对象。 // 自定义结构体构造函数 func NewInfo() *Info {return Info{Email: 123163.com,Phone: 123456,} }func function29() {a : NewInfo()fmt.Println(a) // {123163.com 123456} }内存对齐 内存对齐同 C 语言类似不过多阐述。 需要注意的是一个空的结构体不占用内存空间但是当一个结构体最后一个字段是空结构体编译器会额外填充 1 字节。 func function25() {fmt.Println(unsafe.Sizeof(struct{}{})) // 0type structA struct {A int8 // 1 byteB struct{} // 0 byte}var a structAfmt.Println(unsafe.Sizeof(a)) // 2 }这是为了防止对结构体最后一个零内存占用字段进行取地址操作时发生越界而空结构体不放最后一个字段不会额外填充。 当然额外填充一字节也是会进行内存对齐的unsafe.Alignof 返回变量的对齐要求 func function26() {type structA struct {A int32 // 4 byteB struct{} // 0 byte}var a structAfmt.Println(unsafe.Sizeof(a), unsafe.Alignof(a)) // 8 4 }JSON 序列化与反序列化 利用 encoding/json 包的 json.Marshal 和 json.Unmarshal 进行序列化和反序列化。 // JSON func function28() {type Phone struct {Price int json:priceName string json:name}s : Phone{Price: 3888,Name: 小米,}s1, _ : json.Marshal(s) // JSON 序列化fmt.Printf(%s\n, s1) // {price:3888,name:小米}var a Phone_ json.Unmarshal(s1, a) // JSON 反序列化fmt.Println(a) // {3888 小米} }上述序列化后字段变为了 tag 定义的名称 price 和 name。 方法和接收者 Go 允许为特定的变量设置专用的函数这个专用的函数被称为方法method。通过方法接收者receiver来绑定方法和对象接收者类似于 this、self。 方法声明 func (接收者 接收者类型) 方法名(参数) (返回值) {方法体 }建议接收者类型名称为首字母小写 接收者类型值接收者、指针接收者 函数传参都是值拷贝实参体积较大或函数内部需要修改实参需要传递实参地址指针保持一致性。一个类型的某个方法使用了指针接收者那么该类型其他方法应该保持一致 通过结构体嵌套进行组合实现面向对象的继承 Go 的语法糖 . 运算符如果是指针则会自动获取变量的地址 Go 通过内嵌其他结构体进行组合每个被嵌入的结构体均会为其提供一些方法。当进行方法调用会先查找当前结构体中是否声明了该方法没有则依此去内嵌字段的方法中查找。 type Course struct {Name stringScore int8 }// 值接收者 func (c Course) getName() string {return c.Name }// 指针接收者 func (c *Course) setScore(score int8) {c.Score score }type Math struct {People int8Course }func function30() {m : Math{People: 36,Course: Course{Name: math,Score: 100,},}fmt.Println(m.Course.Name, m.Score) // math 100m.setScore(120)fmt.Println(m.Course.getName(), m.Course.Score) // math 120 }通过类型定义声明一个新的类型再为其声明方法。 不支持为其他包的类型声明方法不支持为接口类型和基于指针定义的类型定义方法 type MyBool boolfunc (m MyBool) SayType() {fmt.Printf(%T\n, m) }//type PtrMyBool *MyBool //func (p PtrMyBool) SayType() {} // *MyBool is a pointer typefunc function31() {var a MyBoola.SayType() // main.MyBool }补充 Go 中根据首字母的大小写确定访问权限无论是方法名、常量、变量名还是结构体的名称。 首字母大写则可以被其他的包访问首字母小写则只能在本包中使用 可以简单的理解首字母大写是公有的首字母小写是私有的。
http://www.zqtcl.cn/news/761253/

相关文章:

  • 网站建设说明哈尔滨网站建设渠道
  • 一 网站建设管理基本情况设计类的网站
  • wordpress产品编辑如何优化wordpress
  • 网站后台更新缓存失败网站平台规划方案
  • 网站开发需求分析主要内容saas建站系统是怎么实现的
  • 做qq头像的网站有哪些wordpress怎么部署到虚拟linux服务器
  • 征求网站建设企业网站建设word
  • 市民服务中心网站建设小型公众号开发
  • 服装网站建设策划书论文基层建设刊物网站
  • 网站建设合同技术开发合同范本wordpress备份和还原
  • 物流信息平台网站建设一流本科专业建设点网站
  • 天猫网站建设的目标是什么装潢设计软件
  • 电商网站首页图片网站功能模块建设
  • 邮件服务器是不是网站服务器黄江网站建设公司
  • 科技部网站方案网页设计网站设计欣赏
  • 自贡建设机械网站网站策划与运营课程认知
  • 公司做网站该注意哪些廊坊seo
  • 网站开发目录高尔夫 wordpress
  • 三只松鼠网站建设不做网站做百家号
  • 石家庄网站关键词推广淘宝网站建设设计模板
  • 马鞍山什么房产网站做的好网速
  • 国外做兼职网站软件园二期做网站的公司
  • 淘客网站备案教程网页设计与制作教程十四五规划
  • 哪些网站可以做外部锚文本网页设计个人简历怎么做
  • 福州网站营销北京著名网站建设公司
  • 导购网站开发 源码wordpress 获取总页数
  • 网站名查找wordpress评论人
  • 网络推广最好的网站有哪些wordpress怎么用万网域名
  • 大连仟亿科技网站建设公司 概况网络信用贷款哪个好
  • 配置了iis打不开网站外贸建站哪个最便宜