Go系列(六):面向对象

结构体和方法

  • go语言仅支持封装,不支持继承和多态
  • go语言没有class 只有struct
  • go语言没有构造函数的说法
  • 结构创建在堆上还是栈上? 不需要知道
  • 在调用的时候,编译器很聪明的,要值还是指针,编译器会帮我们转换
package main

import "fmt"

type treeNode struct {
	value       int
	left, right *treeNode
}
// 给结构定义方法
// (node treeNode):接受者 这个参数也是传值
// 和普通函数没有区别
func (node treeNode) print(){
	fmt.Println(node.value)
}

// node是传值,所以修改是没有作用的
func (node treeNode) setValue(value int){
	node.value = value // 指针的话,可以赋值
}

// 改成指针
// 只有使用指针才可以改变结构内容
func (node *treeNode) setValuePtr(value int){
	node.value = value
}

// 使用自定义工厂函数
func createNode(value int) *treeNode {
	// 返回了局部变量的地址
	return &treeNode{value: value}
}

func main() {
	var root treeNode
	fmt.Println(root) //{0 <nil> <nil>}

	// 赋值
	root = treeNode{value: 3}
	root.left = &treeNode{}
	root.right = &treeNode{5, nil, nil}
	node := []treeNode{
		{value: 3},
		{},
		{6, nil, &root},
	}// [{3 <nil> <nil>} {0 <nil> <nil>} {6 <nil> 0xc00000c080}]
	root.right.left = new(treeNode)


	root.left.right = createNode(2)
	root.setValue(5)
	fmt.Println(root)//{3 0xc00000c0c0 0xc00000c0e0}
	root.setValuePtr(6)
	fmt.Println(root) // {6 0xc0000a6060 0xc0000a6080}

	fmt.Println(node)
	root.print()
	// nil指针可以调用方法 但是会报错,
	var pRoot *treeNode
	pRoot.setValue(1)
}
值接受者vs指针接受者
  • 要改变内容必须使用指针接受者
  • 结构过大考虑指针接受者
  • 一致性:如有指针接受者,最好使用指针接受者
  • 值接受者是go语言特有的

封装

  • 名字使用CamelCase
  • 首字母大写:public
  • 首字母小写:private
  • 大小写是针对包来讲,仅对包管理有效

  • 每个目录(不含子目录)一个包
  • 包名可以和目录名不一样
  • main包包含可执行入口,main函数必须在main包里才可以执行
  • 为结构定义的方法必须放在同一个包内,但是可以不同的文件

扩展已有类型

  • 如何系统的扩展其他人写的类型,
    • 定义别名
    • 使用组合
    • 使用内嵌
// 使用组合
type myTreeNode struct {
	node *Node //包含原有要扩展的类型,然后在他的基础上,扩展自己想要的功能
}

func (myNode *myTreeNode) postOrder(){
	if myNode ==nil{
		return
	}
	// 遍历左子树
	lNode := myTreeNode{myNode.node.Left}
	lNode.postOrder()

	// 遍历右子树
	rNode := myTreeNode{myNode.node.Right}
	rNode.postOrder()
	
	// 遍历自己
	myNode.node.Print()
	
}



// 使用别名扩展类型
type Queue []int

func (q *Queue) Push(v int) {
	*q = append(*q, v)
}

func (q *Queue) Pop()  int{
	v:=(*q)[0]
	*q = (*q)[1:]
	return v
}


// 使用内嵌
// 使用内嵌可以省略很多代码
 使用内嵌 实质上是省略成员名 将成员变量从包中带过来(包括方法和成员变量)
type myTreeNode struct {
	*Node  // 内嵌方法
}

func (myNode *myTreeNode) postOrder(){
	if myNode ==nil{
		return
	}
	// 遍历左子树
	//lNode := myTreeNode{myNode.Node.Left} 类型的最后一个点的后面是他的名字
	lNode := myTreeNode{myNode.Left} // 也可以直接省略
	lNode.postOrder()

	// 遍历右子树
	rNode := myTreeNode{myNode.Right}
	rNode.postOrder()

	// 遍历自己
	myNode.Print()

}

// 使用内嵌之后,当本身的方法与包中的方法名称一样时,为了区别,调用方法不同
// 这个方法会让Node的方法隐藏起来,要调用的话
// myTree.Print() //调用myTreeNode的Print方法
// myTree.Node.Print() // 调用Node的Print方法
func (myTree *myTreeNode) Print(){
	//。。。。
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第1章 5个例子 1 1.1 开始 1 1.2 编辑、编译和运行 3 1.3 Hello Who? 6 1.4 大数字——二维切片 8 1.5 栈——自定义类型及其方法 12 1.6 americanise示例——文件、映射和闭包 18 1.7 从极坐标到笛卡儿坐标——并发 28 1.8 练习 33 第2章 布尔与数值类型 35 2.1 基础 35 2.2 布尔值和布尔表达式 39 2.3 数值类型 40 2.3.1 整型 42 2.3.2 浮点类型 46 2.4 例子:statistics 53 2.4.1 实现一个简单的统计函数 54 2.4.2 实现一个基本的HTTP服务器 55 2.5 练习 58 第3章 字符串 60 3.1 字面量、操作符和转义 61 3.2 比较字符串 63 3.3 字符和字符串 65 3.4 字符串索引与切片 67 3.5 使用fmt包来格式化字符串 69 3.5.1 格式化布尔值 73 3.5.2 格式化整数 74 3.5.3 格式化字符 75 3.5.4 格式化浮点数 75 3.5.5 格式化字符串和切片 76 3.5.6 为调试格式化 78 3.6 其他字符处理相关的包 80 3.6.1 strings包 81 3.6.2 strconv包 86 3.6.3 utf8包 90 3.6.4 unicode包 91 3.6.5 regexp包 92 3.7 例子:m3u2pls 101 3.8 练习 106 第4章 集合类型 108 4.1 值、指针和引用类型 108 4.2 数组和切片 115 4.2.1 索引与分割切片 119 4.2.2 遍历切片 119 4.2.3 修改切片 121 4.2.4 排序和搜索切片 125 4.3 映射 128 4.3.1 创建和填充映射 129 4.3.2 映射查询 131 4.3.3 修改映射 132 4.3.4 键序遍历映射 132 4.3.5 映射反转 133 4.4 例子 134 4.4.1 猜测分隔符 134 4.4.2 词频统计 136 4.5 练习 141 第5章 过程式编程 144 5.1 语句基础 144 5.1.1 类型转换 147 5.1.2 类型断言 148 5.2 分支 149 5.2.1 if语句 150 5.2.2 switch语句 151 5.3 for循环语句 158 5.4 通信和并发语句 160 5.5 defer、panic和recover 166 5.6 自定义函数 171 5.6.1 函数参数 172 5.6.2 init()函数和main()函数 175 5.6.3 闭包 176 5.6.4 递归函数 178 5.6.5 运行时选择函数 181 5.6.6 泛型函数 183 5.6.7 高阶函数 187 5.7 例子:缩进排序 192 5.8 练习 197 第6章 面向对象编程 199 6.1 几个关键概念 199 6.2 自定义类型 201 6.2.1 添加方法 203 6.2.2 验证类型 207 6.3 接口 209 6.4 结构体 217 6.5 例子 224 6.5.1 FuzzyBool——一个单值自定义类型 224 6.5.2 Shapes——一系列自定义类型 229 6.5.3 有序映射——一个通用的集合类型 240 6.6 练习 248 第7章 并发编程 251 7.1 关键概念 252 7.2 例子 256 7.2.1 过滤器 256 7.2.2 并发的Grep 260 7.2.3 线程安全的映射 266 7.2.4 Apache报告 271 7.2.5 查找副本 278 7.3 练习 285 第8章 文件处理 287 8.1 自定义数据文件 287 8.1.1 处理JSON文件 290 8.1.2 处理XML文件 295 8.1.3 处理纯文本文件 301 8.1.4 处理Go语言二进制文件 307 8.1.5 处理自定义的二进制文件 309 8.2 归档文件 317 8.2.1 创建zip归档文件 317 8.2.2 创建可压缩的tar包 319 8.2.3 解开zip归档文件 321 8.2.4 解开tar归档文件 322 8.3 练习 324 第9章 包 326 9.1 自定义包 326 9.1.1 创建自定义的包 327 9.1.2 导入包 333 9.2 第三方包 334 9.3 Go命令行工具简介 335 9.4 Go标准库简介 336 9.4.1 归档和压缩包 336 9.4.2 字节流和字符串相关的包 336 9.4.3 容器包 337 9.4.4 文件和操作系统相关的包 339 9.4.5 图像处理相关的包 341 9.4.6 数学处理包 341 9.4.7 其他一些包 341 9.4.8 网络包 342 9.4.9 反射包 343 9.5 练习 346 附录A 后记 348 附录B 软件专利的危害 350 附录C 精选书目 353
目录: 第1章 5个例子 1 1.1 开始 1 1.2 编辑、编译和运行 3 1.3 Hello Who? 6 1.4 大数字——二维切片 8 1.5 栈——自定义类型及其方法 12 1.6 americanise示例——文件、映射和闭包 18 1.7 从极坐标到笛卡儿坐标 ——并发 28 1.8 练习 33 第2章 布尔与数值类型 35 2.1 基础 35 2.2 布尔值和布尔表达式 39 2.3 数值类型 40 2.3.1 整型 42 2.3.2 浮点类型 46 2.4 例子:statistics 53 2.4.1 实现一个简单的统计函数 54 2.4.2 实现一个基本的HTTP服务器 55 2.5 练习 58 第3章 字符串 60 3.1 字面量、操作符和转义 61 3.2 比较字符串 63 3.3 字符和字符串 65 3.4 字符串索引与切片 67 3.5 使用fmt包来格式化字符串 69 3.5.1 格式化布尔值 73 3.5.2 格式化整数 74 3.5.3 格式化字符 75 3.5.4 格式化浮点数 75 3.5.5 格式化字符串和切片 76 3.5.6 为调试格式化 78 3.6 其他字符处理相关的包 80 3.6.1 strings包 81 3.6.2 strconv包 86 3.6.3 utf8包 90 3.6.4 unicode包 91 3.6.5 regexp包 92 3.7 例子:m3u2pls 101 3.8 练习 106 第4章 集合类型 108 4.1 值、指针和引用类型 108 4.2 数组和切片 115 4.2.1 索引与分割切片 119 4.2.2 遍历切片 119 4.2.3 修改切片 121 4.2.4 排序和搜索切片 125 4.3 映射 128 4.3.1 创建和填充映射 129 4.3.2 映射查询 131 4.3.3 修改映射 132 4.3.4 键序遍历映射 132 4.3.5 映射反转 133 4.4 例子 134 4.4.1 猜测分隔符 134 4.4.2 词频统计 136 4.5 练习 141 第5章 过程式编程 144 5.1 语句基础 144 5.1.1 类型转换 147 5.1.2 类型断言 148 5.2 分支 149 5.2.1 if语句 150 5.2.2 switch语句 151 5.3 for循环语句 158 5.4 通信和并发语句 160 5.5 defer、panic和recover 166 5.6 自定义函数 171 5.6.1 函数参数 172 5.6.2 init()函数和main()函数 175 5.6.3 闭包 176 5.6.4 递归函数 178 5.6.5 运行时选择函数 181 5.6.6 泛型函数 183 5.6.7 高阶函数 187 5.7 例子:缩进排序 192 5.8 练习 197 第6章 面向对象编程 199 6.1 几个关键概念 199 6.2 自定义类型 201 6.2.1 添加方法 203 6.2.2 验证类型 207 6.3 接口 209 6.4 结构体 217 6.5 例子 224 6.5.1 FuzzyBool——一个单值自定义类型 224 6.5.2 Shapes——一系列自定义类型 229 6.5.3 有序映射——一个通用的集合类型 240 6.6 练习 248 第7章 并发编程 251 7.1 关键概念 252 7.2 例子 256 7.2.1 过滤器 256 7.2.2 并发的Grep 260 7.2.3 线程安全的映射 266 7.2.4 Apache报告 271 7.2.5 查找副本 278 7.3 练习 285 第8章 文件处理 287 8.1 自定义数据文件 287 8.1.1 处理JSON文件 290 8.1.2 处理XML文件 295 8.1.3 处理纯文本文件 301 8.1.4 处理Go语言二进制文件 307 8.1.5 处理自定义的二进制文件 309 8.2 归档文件 317 8.2.1 创建zip归档文件 317 8.2.2 创建可压缩的tar包 319 8.2.3 解开zip归档文件 321 8.2.4 解开tar归档文件 322 8.3 练习 324 第9章 包 326 9.1 自定义包 326 9.1.1 创建自定义的包 327 9.1.2 导入包 333 9.2 第三方包 334 9.3 Go命令行工具简介 335 9.4 Go标准库简介 336 9.4.1 归档和压缩包 336 9.4.2 字节流和字符串相关的包 336 9.4.3 容器包 337 9.4.4 文件和操作系统相关的包 339 9.4.5 图像处理相关的包 341 9.4.6 数学处理包 341 9.4.7 其他一些包 341 9.4.8 网络包 342 9.4.9 反射包 343 9.5 练习 346

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值