Golang - 复合类型

1. 指针

  • go语言中指针是很容易学习的,比C中容易的多,它可以更简单地执行一些任务
  • 与变量类似,使用前需要声明,使用&符号可以取内存地址
  • 声明指针的格式:
    • var 指针变量名 *指针类型

指针的使用

//package 声明开头表示代码所属包
package main import "fmt" func main() {
//声明变量
var a int = 20 //声明指针变量
var p *int
p = &a //十六进制
fmt.Printf("a变量的地址是: %x\n", &a)
fmt.Printf("p变量存储的指针地址: %x\n", p) //使用指针访问值
fmt.Printf("*p变量的值: %d\n", *p)
} //a变量的地址是: c042052080
//p变量存储的指针地址: c042052080
//*p变量的值: 20

通过指针修改变量

//package 声明开头表示代码所属包
package main import "fmt" func main() {
//定义变量
var num int = 10
fmt.Println(&num)
var ptr *int //指针赋值
ptr = &num
//通过指针修改num
* ptr = 20
fmt.Println(num)
} //0xc042052080
//20

go空指针

//package 声明开头表示代码所属包
package main import "fmt" func main() {
var ptr *int
fmt.Println("ptr的值为:", ptr) //判断空指针
if ptr == nil{
fmt.Println("是空")
}
} //ptr的值为: <nil>
//是空

值传递和引用传递

void pass_by_val(int a){
a++;
} void pass_by_ref(int& a){
a++;
} int main() {
int a = 3; pass_by_val(a);
printf("pass_by_val: %d\n", a)
printf("pass_by_ref: %d\n", a)
} 答案:3,4

值传递:

//package 声明开头表示代码所属包
package main import "fmt" func swap(a, b int){
a, b = b, a
} func main() {
a, b := 3, 4
swap(a, b)
fmt.Println(a, b)
} // 3 4

go引用传递:

//package 声明开头表示代码所属包
package main import "fmt" func swap(a, b *int){
*a, *b = *b, *a
} func main() {
a, b := 3, 4
swap(&a, &b)
fmt.Println(a, b)
} // 4 3

2. new()和make()

  • new()用来分配内存,但与其他语言中的同名函数不同,它不会初始化内存,只会将内存置零

  • make(T)会返回一个指针,该指针指向新分配的,类型为T的零值,适用于创建结构体

  • make()的目的不同于new(),它只能创建slice、map、channel,并返回类型为T(非指针)的已初始化(非零值)的值

    //package 声明开头表示代码所属包
    package main import "fmt" func main() {
    p :=new([]int)
    fmt.Println(p) //[]int切片
    //10: 初始化10个长度
    //50: 容量为50
    m :=make([]int, 10, 50)
    fmt.Println(m) m[0] = 10
    (*p)[0] = 10
    fmt.Println(p)
    }

3. 数组

声明变量:

var 数组名[数组长度] 数组类型

声明和初始化数组:

//package 声明开头表示代码所属包
package main import "fmt" func main() {
//数组长度不让变化
//定义int类型数组
var arr1 [5]int //:=声明并赋值
arr2 := [3]int{1, 2, 3} //可以省略大小
arr3 := [10]int{2, 4, 6, 8, 10}
fmt.Println(arr1, arr2, arr3) //定义二维数组
var grid [4][5]int
fmt.Println(grid)
} //[0 0 0 0 0] [1 2 3] [2 4 6 8 10 0 0 0 0 0]
//[[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]

数组是值类型还是引用类型?

package main

import "fmt"

//传入数组,修改元素
func printArr(arr [5]int) {
//修改一个元素
arr[0] = 100
for i,v := range arr{
fmt.Println(i,v)
}
} func main() {
//定义数组
var arr1 [5]int //:=声明并赋值
arr2 := [3]int{1, 2, 3}
//可以省略大小
arr3 := [...]int{2, 4, 6, 8, 10}
fmt.Println(arr1, arr2, arr3) //printArr(arr1)
//报错
//printArr(arr2)
printArr(arr3) //打印原始值
fmt.Println()
fmt.Println(arr3)
}

4. slice

  • 数组的长度在定义之后无法再次修改,go语言提供了数组切片(slice)来弥补数组的不足

  • 创建切片的各种方式

      //package 声明开头表示代码所属包
    package main import "fmt" func main() {
    //声明空切片
    var s1 []int //:=声明
    s2 :=[]int{} var s3 []int = make([]int, 0)
    s4 :=make([]int, 0, 0)
    fmt.Println(s1, s2, s3, s4)
    } [] [] [] []

.

//package 声明开头表示代码所属包
package main import "fmt" func main() {
//定义数组
arr :=[...]int{0, 1, 2, 3, 4, 5, 6, 7} //切片取值
fmt.Println(arr[2:6])
fmt.Println(arr[:6])
fmt.Println(arr[2:])
fmt.Println(arr[:])
} //[2 3 4 5]
//[0 1 2 3 4 5]
//[2 3 4 5 6 7]
//[0 1 2 3 4 5 6 7]

go切片可以向后扩展, 但不能向前扩展

//package 声明开头表示代码所属包
package main import "fmt" func main() {
//定义数组
arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
s1 := arr[2:6]
fmt.Println(s1)
s2 := s1[3:5]
fmt.Println(s2) //切片添加元素
s3 := append(s2,10)
fmt.Println(s3)
fmt.Println(arr) s4 := append(s3,11)
fmt.Println(s4)
fmt.Println(arr)
s5:= append(s4,12)
fmt.Println(s5)
fmt.Println(arr)
} //[2 3 4 5]
//[5 6]
//[5 6 10]
//[0 1 2 3 4 5 6 10]
//[5 6 10 11]
//[0 1 2 3 4 5 6 10]
//[5 6 10 11 12]
//[0 1 2 3 4 5 6 10]

内建函数copy()

//package 声明开头表示代码所属包
package main import "fmt" func main() {
//切片
data := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s1 := data[8:]
s2 := data[:5]
fmt.Println(s1)
fmt.Println(s2) //将第二个拷贝到第一个里
copy(s2, s1)
fmt.Println(s2)
fmt.Println(data)
} //[8 9]
//[0 1 2 3 4]
//[8 9 2 3 4]
//[8 9 2 3 4 5 6 7 8 9]

5. Map

  • Map 是go内置的数据结构,是一种无序的键值对的集合,可以通过key快速找到value的值
  • 定义Map:
    • var 变量名 map[key的数据类型] value的数据类型

    • 创建map

      	//package 声明开头表示代码所属包
      package main import "fmt" func main() {
      //声明map
      var mmp map[int]string
      fmt.Println(mmp == nil) //m2和m3是等价的
      m2 := map[int]string{}
      m3 :=make(map[int]string)
      fmt.Println(m2, m3) m4 :=make(map[int]string, 10)
      fmt.Println(m4)
      } //true
      //map[] map[]
      //map[]

初始化map

//package 声明开头表示代码所属包
package main import "fmt" func main() {
//1. 定义同时初始化
var m1 map[int]string = map[int]string{1:"超哥", 2:"最帅"}
fmt.Println(m1) //2. 自动推导类型 :=
m2 :=map[int]string{1:"超哥", 2:"最帅"}
fmt.Println(m2)
} //map[1:超哥 2:最帅]
//map[1:超哥 2:最帅]

键值操作

//package 声明开头表示代码所属包
package main func main() {
m1 :=map[int]string{1:"111",2:"222"} //修改
m1[1]="1111"
//追加
m1[3]="333"
}

6. 结构体

  • go语言没有class,只是个结构体struct
  • 结构体定义:
    • type 结构体名 struct{}
  • 结构体初始化

//package 声明开头表示代码所属包

package main

import "fmt"

//定义学生结构体
type Student struct {
id int
name string
sex byte
age int
addr string
} func main() {
//1.顺序初始化
var s1 Student = Student{1,"约汉",'f',18,"bj"}
fmt.Println(s1)
s2 := Student{2,"接客",'m',20,"sh"}
fmt.Println(s2)
//s3 := Student{3,"撸死",'m',25} //2.指定初始化成员
s4 := Student{id:4,age:26}
fmt.Println(s4)
fmt.Println(s4.id) //3.结构体作为指针变量初始化
var s5 *Student = &Student{5,"接客",'f',20,"sh"}
fmt.Println(s5)
//指针类型访问变量
//go底层自己实现了转换,下面2种都可以取指针对象的属性
fmt.Println((*s5).id)
fmt.Println(s5.id) s6 := &Student{6,"接客",'m',20,"sh"}
fmt.Println(s6)
} //{1 约汉 102 18 bj}
//{2 接客 109 20 sh}
//{4 0 26 }
//4
//&{5 接客 102 20 sh}
//5
//5
//&{6 接客 109 20 sh}

7. 结构体参数

结构体可以作为函数参数传递

//package 声明开头表示代码所属包
package main import "fmt" type Student struct {
id int
name string
sex string
age int
addr string
} //定义传递学生对象的方法
func tmpStudent(tmp Student) {
//修改id
tmp.id = 250
fmt.Println("tmp=", tmp)
} //定义传递指针类型的对象的方法
func tmpStudent2(p *Student) {
//修改id
p.id = 249
fmt.Println("tmp2=", p)
} func main() {
var s Student = Student{1, "接客", "female", 20, "sz"}
tmpStudent(s)
fmt.Println("main s =", s)
//传递指针地址
tmpStudent2(&s)
fmt.Println("main s2=", s)
} //tmp= {250 接客 female 20 sz}
//main s = {1 接客 female 20 sz}
//tmp2= &{249 接客 female 20 sz}
//main s2= {249 接客 female 20 sz}

Golang - 复合类型的更多相关文章

  1. 带你学够浪:Go语言基础系列 - 8分钟学复合类型

    ★ 文章每周持续更新,原创不易,「三连」让更多人看到是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) " 对于一般的语言使用者来说 ,20% ...

  2. golang枚举类型 - iota用法拾遗

    在c#.java等高级语言中,经常会用到枚举类型来表示状态等.在golang中并没有枚举类型,如何实现枚举呢?首先从枚举的概念入手. 1.枚举类型定义 从百度百科查询解释如下:http://baike ...

  3. 第54讲:Scala中复合类型实战详解

    今天学习了scala的复合类型的内容,让我们通过实战来看看代码: trait Compound_Type1trait Compound_Type2class Compound_Type extends ...

  4. 实现在GET请求下调用WCF服务时传递对象(复合类型)参数

    WCF实现RESETFUL架构很容易,说白了,就是使WCF能够响应HTTP请求并返回所需的资源,如果有人不知道如何实现WCF支持HTTP请求的,可参见我之前的文章<实现jquery.ajax及原 ...

  5. go语言 类型:基础类型和复合类型

    Go 语言中包括以下内置基础类型:布尔型:bool整型:int int64 int32 int16 int8 uint8(byte) uint16 uint32 uint64 uint浮点型:floa ...

  6. C语言中的复合类型

    复合类型 一.掌握的类型 1. 指针数组 int * arr[10]; //arr是一个数组,有10个元素,每个元素都是一个指针,即arr是一个指针数组 int a,b,c,d; arr[0] = & ...

  7. 学习C++.Primer.Plus 4 复合类型

    本章介绍的有复合类型有: 数组. 字符串. 结构. 共用体. 指针 数组: 声明数组时数组长度必须为常量(或const). 只有初始化时可以用“=”,其它时候均不可以给数组直接赋值,除了赋值的元素以外 ...

  8. C++Primer快速浏览笔记-复合类型

    C++Primer2.3节介绍了两种复合类型:引用和指针 1.引用 引用并非对象,它只是为一个已经存在的对象所起的别名. 一旦初始化完成,引用将和它的初始值对象一直绑定在一起,不能重新绑定到另一个对象 ...

  9. Scala 深入浅出实战经典 第54讲:Scala中复合类型实战详解

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

随机推荐

  1. 【BASH】bash shell的使用实例

    ************************************************************************ ****原文:blog.csdn.net/clark_ ...

  2. 《黑马程序猿》 cocos2d游戏引擎复习笔记一

    /** ----------------------------游戏场景的搭建-------------------------------- 1首先创建一个surfaceview ,它能够在子线程中 ...

  3. poj--3187--Backward Digit Sums(dfs)

    Backward Digit Sums Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5667   Accepted: 32 ...

  4. poj2594——最小路径覆盖

    Description Have you ever read any book about treasure exploration? Have you ever see any film about ...

  5. B1257 [CQOI2007]余数之和 数学,分块

    这个题想明白之后很好做,但是不好想.我根本没想出来,上网看了一下才知道怎么做... 这个题其实得数是一个等差数列,然后一点点求和就行了. 上次NOIP就是没看出来规律,这次又是,下次先打表找规律!!! ...

  6. 【原创分析帖】据说Google内部有史以来最难的一道面试题

    逛技术平台的时候,刷到一道算法题,一眼看去,就被其开头吸引了: 摘自知乎某 Google 分布式大神的一道题,技术是Google内部出的有史以来最难的一道题 嗯,距离下班还有一段时间,就看看把. 题目 ...

  7. APP加固反调试(Anti-debugging)技术点汇总

    0x00 时间相关反调试 通过计算某部分代码的执行时间差来判断是否被调试,在Linux内核下可以通过time.gettimeofday,或者直接通过sys call来获取当前时间.另外,还可以通过自定 ...

  8. JSP页面中path和basepath的含义

    今天在看代码时,发现程序使用了 request.getScheme() .不明白是什么意思,查了一下.结果整理如下: 1.request.getScheme() 返回当前链接使用的协议:一般应用返回h ...

  9. 利用windbg获取dump的dll文件

    根据堆栈对应的地址查找其对应的Module ID,然后将对应的Module保存. !IP2MD 命令从托管函数中获取 MethodDesc 结构地址. !dumpmodule 1caa50 下面的命令 ...

  10. web通信之跨文档通信 postMessage

    index.html <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type&qu ...