type Circle struct {
radius float64
desc string
} //定义结构体里面的方法
func (c Circle) getArea() float64 {
return 3.14 * c.radius * c.radius
} //如果想要改变结构体里面的成员变量,就必须传入指针,否则的话是不生效的
func (c *Circle) setRadius(val float64) {
c.radius = val
} //因为没有传入指针,所以这里的Circle对象被拷贝了,因此不生效
func (c Circle) setRadiusFake(val float64) {
c.radius = val
} /*
方法学习,其实就是类似于类里面的函数,但是go没有类这个东西
*/
func method_test() {
print_start_seperator("method_test");
var cir Circle;
cir.radius = 12;
fmt.Printf("circle's area:%f \n", cir.getArea()) cir.setRadius(10)
fmt.Printf("after real setRadius[%f] circle's area:%f \n", cir.radius, cir.getArea()) cir.setRadiusFake(20)
fmt.Printf("after fake setRadius[%f] circle's area:%f \n", cir.radius, cir.getArea())
print_end_seperator();
} /**
没有指定大小,是切片,在go里面是指针传递
*/
func slice_func(arr []int) {
for idx, val := range arr {
fmt.Printf("[slice_func]idx:%d val:%d \t", idx, val)
}
fmt.Println("")
} /**
指定了大小,是数组,在go里面是值传递
*/
func arr_func(arr [5]int) {
for idx, val := range arr {
fmt.Printf("[arr_func]idx:%d val:%d \t", idx, val)
}
fmt.Println("")
} /**
修改array里面的值,由于数组是值传递,因此这里对原有的参数没有任何影响
*/
func change_arr(arr [5]int, val int) {
for idx, _ := range arr {
arr[idx] = val * 10
}
} /**
切片是指针传递,因此这里的修改对原有值会有影响
其实本质上这样的写法,切片也是值传递,只是因为在go中切片存储的结构体里面具体的数值是个指针,所以值传递
也只是拷贝了这部分指针的地址,修改的是同一片内存,go中的切片存储的方式如下:
type Slice struct{
arr *int
size int
cap int
}
*/
func change_slice(arr []int, val int) {
for idx, _ := range arr {
arr[idx] = val * 10
}
} /**
工具函数,打印数组
*/
func print_arr(arr [5]int) {
for _, val := range arr {
fmt.Printf("%d\t", val)
}
fmt.Println("")
} /**
工具函数,打印切片
*/
func print_slice(arr []int) {
if nil == arr {
return
} for _, val := range arr {
fmt.Printf("%d\t", val)
}
fmt.Println("")
} /**
工具函数,打印切片
*/
func print_slice_str(arr []string) {
if nil == arr {
return
} for _, val := range arr {
fmt.Printf("%s\t", val)
}
fmt.Println("")
} /*
数组和切片学习,数组和切片在go中是两种完全不同的类型,不要搞混了。
*/
func array_slice_test() {
print_start_seperator("array_slice_test")
arr := []int{5, 4, 3, 2, 1}
slice_func(arr)
//没有指定大小的参数只能传给没有指定大小的函数
//arr_func(arr) arr2 := [5]int{10, 9, 8, 7, 6}
//slice_func(arr2)
arr_func(arr2) //下面的数组虽然只是声明,因为指定了大小,所以默认初始化为0
var arr3 [5]int
for _, val := range arr3 {
fmt.Printf("val:%d \t", val)
}
fmt.Println() //没有指定大小,是切片,在go里面和数组是完全不同的类型,所以arr3本质上是nil,for循环将不会执行
var arr4 []int
for _, val := range arr4 {
fmt.Printf("%d", val)
fmt.Println("I am not executed!!!!")
} if nil == arr4 {
fmt.Println("arr4 is a nil!!!!!!!!!!!!!")
} //数组是值传递
var arr5 [5]int = [5]int{0, 0, 0, 0, 0}
change_arr(arr5, 15)
fmt.Println("After changing the array...")
print_arr(arr5) /**
本质上切片也是值传递,只是因为在go中切片存储的结构体里面具体的数值是个指针,所以值传递
也只是拷贝了这部分指针的地址,修改的是同一片内存,go中的切片存储的方式如下:
type Slice struct{
arr *int
size int
cap int
}
*/
var arr6 []int = []int{0, 0, 0, 0, 0, 0, 0}
change_slice(arr6, 15)
fmt.Println("After changing the slice...")
print_slice(arr6) //使用数组进行切片的初始化
var arr7 = [5]string{"one", "two", "three", "four", "five"}
slice1 := arr7[:]
print_slice_str(slice1) slice1 = arr7[1:3]
print_slice_str(slice1)
//slice获取的是原来数组的一段数组引用,因此这里的修改会在原数组上面体现到
slice1[0] = "new_two"
fmt.Printf("After assign to slice. arr7:%s slice1:%s\n", arr7, slice1) //After assign to slice. arr7:[one two new_two four five] slice1:[two new_two] //此时如果修改原数组呢?
arr7[1] = "newer_two"
//此时切片也生效了,也就是说,他们始终引用的是同一片地址
fmt.Printf("After assign to origin arr. arr7:%s slice1:%s\n", arr7, slice1) //After assign to origin arr. arr7:[one newer_two three four five] slice1:[newer_two three] //第一个参数为size,第二个参数为capacity
var slice2 = make([]int, 3, 10)
fmt.Printf("slice2. size:%d cap:%d\n", len(slice2), cap(slice2)) //可以通过append来增加slice的数据,记住,这里要接受返回的值
slice2 = append(slice2, 1)
slice2 = append(slice2, 2, 3, 4)
fmt.Printf("After append. slice2:%d\n", slice2) //[0 0 0 1 2 3 4] //注意append函数是生成了一个新得切片,原来得切片对象不会有任何改变
slice2_bak := append(slice2, 10, 11, 12)
fmt.Printf("After append. slice2:%d slice2_bak:%d\n", slice2, slice2_bak) //After append. slice2:[0 0 0 1 2 3 4] slice2_bak:[0 0 0 1 2 3 4 10 11 12] var slice3 = make([]int, len(slice2), cap(slice2))
copy(slice3, slice2)
fmt.Printf("After copy slice. slice3:%d\n", slice3)
//注意,一定要指明slice的长度,否则copy将没有任何效果
var slice4 []int
copy(slice4, slice2)
fmt.Printf("After copy slice. slice4:%d\n", slice4) //[] slice_append()
print_end_seperator()
} /**
slice里面一个需要注意的现象
*/
func slice_append() {
//注意,这里指定了slice的cap为10
slice := make([]int, 5, 10)
for i := 0; i < 5; i++ {
slice[i] = i
} slice1 := slice
slice_p := &slice
fmt.Printf("slice:%d slice1:%d slice_p:%d\n", slice, slice1, *slice_p)
fmt.Printf("slice's addr:%p \n", &slice) //接下来修改slice, 由于slice的cap为10,这里长度够,所以并没有申请新的内存,所以这里slice里面的数组地址没有变化,slice本身也不会变化
slice = append(slice, 10, 11, 12)
fmt.Printf("After append. slice:%d slice1:%d slice_p:%d\n", slice, slice1, *slice_p)
fmt.Printf("After append, slice's addr:%p \n", &slice) //注意,这里指定了slice的cap为6
slice2 := make([]int, 5, 6)
for i := 0; i < 5; i++ {
slice2[i] = i
} slice3 := slice2
slice2_p := &slice2
fmt.Printf("slice2:%d slice3:%d slice2_p:%d\n", slice2, slice3, *slice2_p)
fmt.Printf("slice2's addr:%p \n", &slice2) //接下来修改slice, 由于slice的cap为6,长度不够了,所以会申请新的内存,此时注意,只是slice结构体里面的数组地址发生了变化
//但是对于slice这个结构体本身,其地址并没有发生变化,所以看到的地址也没有变
fmt.Printf("slice.size:%d slice.cap:%d\n", len(slice2), cap(slice2))
slice2 = append(slice2, 10, 11, 12, 13, 14, 15, 16, 17)
fmt.Printf("After append. slice2:%d slice3:%d slice2_p:%d\n", slice2, slice3, *slice2_p)
fmt.Printf("After append, slice2's addr:%p \n", &slice2)
}

Golang学习(用代码来学习) - 第二篇的更多相关文章

  1. Golang学习(用代码来学习) - 第一篇

    package main import ( "fmt" "time" "unsafe" ) //示例代码 var isActive bool ...

  2. 学习KnockOut第二篇之Counter

                                                                        学习KnockOut第二篇之Counter        欲看此 ...

  3. 老老实实学习WCF[第二篇] 配置wcf

    老老实实学WCF 第二篇 配置WCF 在上一篇中,我们在一个控制台应用程序中编写了一个简单的WCF服务并承载了它.先回顾一下服务端的代码: using System; using System.Col ...

  4. 从别人的代码中学习golang系列--01

    自己最近在思考一个问题,如何让自己的代码质量逐渐提高,于是想到整理这个系列,通过阅读别人的代码,从别人的代码中学习,来逐渐提高自己的代码质量.本篇是这个系列的第一篇,我也不知道自己会写多少篇,但是希望 ...

  5. 从别人的代码中学习golang系列--03

    这篇博客还是整理从https://github.com/LyricTian/gin-admin 这个项目中学习的golang相关知识. 作者在项目中使用了 github.com/casbin/casb ...

  6. RabbitMQ学习总结 第二篇:快速入门HelloWorld

    目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...

  7. #Java学习之路——基础阶段二(第二篇)

    我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...

  8. 20172327 2018-2019-1 《第一行代码Android》第二章学习总结

    学号 2017-2018-2 <第一行代码Android>第二章学习总结 教材学习内容总结 - 活动是什么: 活动(Activity)是最容易吸引用户的地方,它是一种可以包含用户界面的组件 ...

  9. angularjs学习第三天笔记(过滤器第二篇---filter过滤器及其自定义过滤器)

    您好,我是一名后端开发工程师,由于工作需要,现在系统的从0开始学习前端js框架之angular,每天把学习的一些心得分享出来,如果有什么说的不对的地方,请多多指正,多多包涵我这个前端菜鸟,欢迎大家的点 ...

  10. JavaWeb学习总结第二篇--第一个JavaWeb程序

    JavaWeb学习总结第二篇—第一个JavaWeb程序 最近我在学院工作室学习并加入到研究生的项目中,在学长学姐的带领下,进入项目实践中,为该项目实现一个框架(用已有框架进行改写).于是我在这里记录下 ...

随机推荐

  1. UVA OJ 623 500!

    500!  In these days you can more and more often happen to see programs which perform some useful cal ...

  2. .Net Core with 微服务 - 架构图

    上一次我们简单介绍了什么是微服务(.NET Core with 微服务 - 什么是微服务 ).介绍了微服务的来龙去脉,一些基础性的概念.有大佬在评论区指出说这根本不是微服务.由于本人的能力有限,大概也 ...

  3. java基础——何为方法

    方法 java中方法时语句的集合,他们在一起执行一个功能 方法时解决一类问题的步骤的有序组合 方法包含于与类或者对象中 方法在程序中被创建,在其他地方被引用 设计方法的原则:保持其原子性. 就是一个方 ...

  4. 【转载】一次「Too many open files」故障

    一次「Too many open files」故障 发表于2015-08-02 昨天,项目的 ElasticSearch 服务挂了,我说的挂可不是进程没了,因为有 Supervisor 保护,而是服务 ...

  5. 二进制部署K8S-3核心插件部署

    二进制部署K8S-3核心插件部署 5.1. CNI网络插件 kubernetes设计了网络模型,但是pod之间通信的具体实现交给了CNI往插件.常用的CNI网络插件有:Flannel .Calico. ...

  6. K8S的资源管理

    K8S的资源管理 管理K8S资源的三种基本方法: 陈述式资源管理方法-使用cli工具进行管理. 声明式资源管理方式-主要依耐资源配置清单. GUI式资源管理方法-主要依耐图形界面. 陈述式资源管理方法 ...

  7. 从CentOS7默认安装的/home中转移空间到根目录/ - LVM操作简明教程

    一.基础概念 Cent0S 7默认启用LVM2(Logical Volume Manager),把机器的一块硬盘分为两个区sda1和sda2,其中分区sda1作为系统盘/boot挂载,少量空间:sda ...

  8. 记一次 .NET 某电商交易平台Web站 CPU爆高分析

    一:背景 1. 讲故事 已经连续写了几篇关于内存暴涨的真实案例,有点麻木了,这篇换个口味,分享一个 CPU爆高 的案例,前段时间有位朋友在 wx 上找到我,说他的一个老项目经常收到 CPU > ...

  9. volatile 关键字笔记

    你应该知道的 volatile 关键字 当一个变量被 volatile 修饰时,任何线程对它的写操作都会立即刷新到主内存中,并且会强制让缓存了该变量的线程中的数据清空,必须从主内存重新读取最新数据. ...

  10. V $ BACKUP_DATAFILE

    V$BACKUP_DATAFILE 从控制文件显示有关备份集中的控制文件和数据文件的信息. 柱 数据类型 描述 RECID NUMBER 备份数据文件记录ID STAMP NUMBER 备份数据文件记 ...