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. 如何在Mac OS X中开启VIM语法高亮和显示行号

    VIM (Wikipedia图) Vim 是一款相当给力的源自UNIX平台的命令行文本编辑器,不过不给力的是,Mac OS X下并没有诸多Linux发行版上VIM那些牛逼哄哄的神马代码高亮显示啊,自动 ...

  2. 【近取 key】功能规格说明书

    目录 前置信息说明 概念介绍 记忆宫殿 A4纸背单词法 词图 单词掌握程度相关 用户和典型场景 系统功能设计 主页 词图相关功能 创建词图 查看词图 复习词图 个人控制台相关功能 我的词图 统计信息 ...

  3. [刷题] PTA 03-树2 List Leaves

    程序: 1 #include <stdio.h> 2 #include <queue> 3 #define MaxTree 20 4 #define Null -1 5 usi ...

  4. SpringMVC Jackson 库解析 json 串属性名大小写自动转换问题

    问题描述 在项目开发中,当实体类和表中定义的某个字段为 RMBPrice,首字母是大写的,sql 查询出来的列名也是大写的 RMBPrice,但是使用 jquery 的 ajax 返回请求响应时却出错 ...

  5. MongoDB(7)- 文档插入操作

    插入方法 db.collection.insertOne() 插入单条文档到集合中 db.collection.insertMany() 插入多条文档到集合中 db.collection.insert ...

  6. Hadoop MapReduce 一文详解MapReduce及工作机制

    @ 目录 前言-MR概述 1.Hadoop MapReduce设计思想及优缺点 设计思想 优点: 缺点: 2. Hadoop MapReduce核心思想 3.MapReduce工作机制 剖析MapRe ...

  7. Jmeter+Ant+Jenkins接口自动化框架

    最近应公司要求,搭建一套接口自动化环境.看到通知邮件,没有多想就确定了Jmeter路线.可能有些人会 说,为啥不用python,相对而言高大上一些.因为公司内部现在项目有用到Jmeter,正好可以结合 ...

  8. Element-ui Popconfirm气泡确认框的确认及取消事件不生效

    Element-ui 官方文档对 Popconfirm气泡确认框的一些属性及事件的描述不够详细,导致第一次使用时会遇到各种各样的问题 对确定事件及取消事件描述如下: 但是如果给组件绑定@confirm ...

  9. Linux的top命令cpu占用少,但是显示很高

    最近发现服务器一个奇怪的问题,40核的双路服务器,装的centos7.4系统,开机过几个小时后会图形界面特别卡顿,top里发现CPU使用率50%左右,但是进程里没有大量占用的进程.怎么上传不了图片.. ...

  10. Jmeter- 笔记9 - CLI(无图形界面)

    使用CLI模式,减少资源占用 用GUI调试好脚本 在jmeter的bin文件夹运行cmd,然后输入命令:jmeter -n -t [jmx file] -l [results file] -e -o ...