百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

golang 复数类型——数组

toyiye 2024-06-27 01:05 14 浏览 0 评论

数组是指一系列同一类型数据的集合。 数组中包含的每个数据被称为数组元素(element), 一个数组包含的元素个数被称为数组的长度。

数组的长度必须是常量, 且是类型的组成部分。[2]int 和 [3]int 是不同类型

var n int = 10;
var a [n]int //err, non-constant array bound n
var b [10]int

注意: 数组的长度不能使用变量, 但可以使用常量;

操作数组

数组的每个元素可以通过索引下标来访问, 索引下标的范围是从0开始到数组长度减1的位置。

package main //必须有个main包
import (
        "fmt"
)
func main() {
        var a [10]int
        //数组遍历赋值
        for i := 0; i < 10; i++ {
            a[i] = i + 1
            fmt.Printf("a[%d] = %d\n", i, a[i])
        }
        //数组的遍历:for
        for i := 0; i < len(a); i++ {
            fmt.Println("a[", i, "] = ", a[i])
        }
        //数组的遍历:for ... range
        for i, v := range a {
            fmt.Println("a[", i, "] = ", v)
        }
}

内置函数len(长度), cap(容量)都返回数组长度(元素数量)

package main //必须有个main包
import(
				"fmt"
)
func main(){
        a := [10]int{} //简短模式声明数组 {} 不能省略
        fmt.Println(len(a), cap(a)) // 10 10
}

初始化数组使用方法:

package main //必须有个main包
import(
				"fmt"
)
func main(){

        a := [3]int{1, 2} //初始化数组
        b := [...]int{1, 2, 3} //通过初始化值确定数组长度
        c := [5]int{2: 100, 4: 200} //通过索引号初始化元素, 未初始化元素值为0
        d := [3]int{} //未初始化元素值为0, 注意: 简短声明数组 {} 括号不能省略
        var f [3]int //未初始化元素值为0
        fmt.Println(a, b, c, d, f) //[1 2 0] [1 2 3] [0 0 100 0 200] [0 0 0] [0 0 0]
        //支持多维数组
        g := [4][2]int{{10, 11}, {20, 21}, {30, 31}, {40, 41}}
        h := [...][2]int{{10, 11}, {20, 21}, {30, 31}, {40, 41}} //第二位数组不能写成"...", 只能写一个[...]
        j := [4][2]int{1:{20, 21}, 3:{40, 41}}
        k := [4][2]int{1:{0: 20}, 3:{1: 41}}
        fmt.Println(g, h, j, k) //[[10 11] [20 21] [30 31] [40 41]] [[10 11] [20 21] [30 31] [40 41]] [[0 0] [20 21] [0 0] [40 41]] [[0 0] [20 0] [0 0] [0 41]]

        var m [5]int = [5]int{1, 2, 3, 4, 5}
        fmt.Println(m) //[1 2 3 4 5]


        var n [5]int = [5]int{1, 2, 3, 4}
        fmt.Println(n) //[1 2 3 4 0]

        //var x [5]int = [5]int{1, 2, 3, 4, 5, 6}
        //fmt.Println(x) //err, array index 5 out of bounds [0:5]
        }

注意: 定义的数组元素的数量不能超过数组的长度

相同类型的数组之间可以使用 == 或 != 进行比较, 也可以相互赋值, 但不可以使用 < 或 >。

package main //必须有个main包
import(
        "fmt"
)
func main(){
        a := [3]int{1, 2, 3}
        b := [3]int{1, 2, 3}
        c := [3]int{1, 3}

        //数组进行比较
        fmt.Println(a == b, b == c) //true false

        var d [3]int
        //数组进行赋值操作
        d = a
        fmt.Println(d) //[1, 2, 3]

        //不同类型(包括长度不同)的数组, 不能进行赋值
        var f [4]int
        //f = a //err, cannot use a (type [3]int) as type [4]int in assignment
        fmt.Println(f)

        //数组进行比较
        fmt.Println(c == d) //err, invalid operation: c == d (mismatched types [3]int and [4]int)
}

注意: 数组进行赋值或者比较时, 数组的长度和类型要相同

package main //必须有个main包
import(
				"fmt"
)
func main(){
        a := [5]int{1, 2, 3, 4, 5}
        b := [5]int{1, 3, 2, 4, 5}

        fmt.Println("a == b", a == b) //false 数组的顺序不相同返回的结果值: false
}

在函数间传递数组

根据内存和性能来看, 在函数间传递数组是一个开销很大的操作。在函数之间传递变量时, 总是以值的方式传递的。

如果这个变量是一个数组, 意味着整个数组, 不管有多长, 都会完成赋值, 并传递给函数。

package main //必须有个main包
import(
        "fmt"
)
func modify(array [5]int){
        array[0] = 10 //试图修改数组的第一个元素
        fmt.Println("In modify(), array values:", array)
}
func main(){
        array := [5]int{1, 2, 3, 4, 5} //定义并初始化一个数组
        modify(array) //In modify(), array values: [10 2 3 4 5]

        fmt.Println("In modify(), array values:", array) //In modify(), array values: [1 2 3 4 5]
}

数组指针作为函数的参数

package main //必须有个main包
import(
        "fmt"
)
func modify(array *[5]int){
        (*array)[0] = 10 //试图修改数组的第一个元素
        fmt.Println("In modify(), array values:", *array)
}
func main(){
        array := [5]int{1, 2, 3, 4, 5} //定义并初始化一个数组
        modify(&array) //In modify(), array values: [10 2 3 4 5]

        fmt.Println("In modify(), array values:", array) //In modify(), array values: [10 2 3 4 5]
}

总结:

1. 数组:是同一种数据类型的固定长度的序列。

2. 数组定义:var a [len]int, 比如:var a [5]int, 数组长度必须是常量, 且是类型的组成部分。一旦定义, 长度不能变。

3. 长度是数组类型的一部分, 因此,var a[5] int和var a[10]int是不同的类型。

4. 数组可以通过下标进行访问, 下标是从0开始, 最后一个元素下标是:len-1

for i := 0; i < len(a); i++ {
}
for index, v := range a {
}

5. 访问越界, 如果下标在数组合法范围之外, 则触发访问越界, 会panic

6. 数组是值类型, 赋值和传参会复制整个数组, 而不是指针。因此改变副本的值, 不会改变本身的值。

7. 支持 "=="、"!=" 操作符, 因为内存总是被初始化过的。

8. 指针数组 [n]*T, 数组指针 *[n]T。

【实例】:一维数组初始化和定义

package main
import (
				"fmt"
)
var arr0 [5]int = [5]int{1, 2, 3}
var arr1 = [5]int{1, 2, 3, 4, 5}
var arr2 = [...]int{1, 2, 3, 4, 5, 6}
var str = [5]string{3: "hello world", 4: "tom"}
func main() {
        a := [3]int{1, 2} // 未初始化元素值为 0。
        b := [...]int{1, 2, 3, 4} // 通过初始化值确定数组长度。
        c := [5]int{2: 100, 4: 200} // 使用引号初始化元素。
        d := [...]struct {
        name string
        age uint8
        }{
        {"user1", 10}, // 可省略元素类型。
        {"user2", 20}, // 别忘了最后一行的逗号。
        }
        fmt.Println(arr0, arr1, arr2, str)
        fmt.Println(a, b, c, d)
}

【实例】: 二维数组初始化和定义

package main
import (
        "fmt"
)
var arr0 [5][3]int
var arr1 [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}
func main() {
        a := [2][3]int{{1, 2, 3}, {4, 5, 6}}
        b := [...][2]int{{1, 1}, {2, 2}, {3, 3}} // 第 2 维度不能用 "..."。
        fmt.Println(arr0, arr1)
        fmt.Println(a, b)
}

【实例】

[10]int 和 [20]int是不同类型([...]int 和 [5]int 是不同的数组类型)

package main
import (
"fmt"
)
func printArray(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, 3, 5}
        arr3 := [...]int{2, 4, 6, 8, 10}
        var grid [4][5]int
        fmt.Println(arr1, arr2, arr3)
        fmt.Println(grid)
        for i := 0; i < len(arr3); i++ { //i++ 后面的要留有空
                fmt.Println(arr3[i])
        }
        for i, v := range arr3 {
                //fmt.Println(arr3[i])
                fmt.Println(i, v)
        }
        for _, v := range arr3 {
                fmt.Println(v)
        }
        //fmt.Printf(&arr3) //[...]int 和 [5]int 是不同的数组类型
        fmt.Println(&arr1)
}

解决方法: 使用切片传递变长的数据

package main
import (
        "fmt"
)
func printArray(arr []int) {
        arr[0] = 100
        for i, v := range arr {
        fmt.Println(i, v)
        }
}
func main() {
          var arr1 [5]int
          arr2 := [3]int{1, 3, 5}
          arr3 := [...]int{2, 4, 6, 8, 10}
          var grid [4][5]int
          fmt.Println(arr1, arr2, arr3)
          fmt.Println(grid)
          for i := 0; i < len(arr3); i++ { //i++ 后面的要留有空
          fmt.Println(arr3[i])
          }
          for i, v := range arr3 {
          //fmt.Println(arr3[i])
          fmt.Println(i, v)
          }
          for _, v := range arr3 {
          fmt.Println(v)
          }
          s := arr3[:] //使用切片的方法,解决变长的数据
          printArray(s)
}

【实例】

冒泡排序算法:

package main //必须有个main包
import(
"fmt"
"math/rand"
"time"
)
func main(){
//设置种子, 只需一次
//如果种子参数一样, 每次运行程序产生的随机数都一样
rand.Seed(time.Now().UnixNano()) //以当前系统时间作为种子参数 nano: 纳米
var a [10]int
n := len(a)

for i := 0; i < n; i++ {
//产生随机数
a[i] = rand.Intn(100) //100以内的随机数
fmt.Printf("%d, ", a[i])
}
fmt.Printf("\n")

//冒泡排序, 挨着的2个元素比较, 升序(大于则交换)
for i := 0; i < n-1; i++ {
for j := 0; j < n-1-i; j++ {
if a[j] > a[j+1] {
a[j], a[j+1] = a[j+1], a[j]
}
}
}

fmt.Printf("\n排序后:\n")
for i := 0; i < n; i++ {
fmt.Printf("%d, ", a[i])
}
fmt.Printf("\n")
}
/*
6, 12, 6, 84, 32, 32, 80, 8, 38, 4,
排序后:
4, 6, 6, 8, 12, 32, 32, 38, 80, 84,
*/


实例: 计算数组的个数

package main
import (
"fmt"
)
func main() {
        arr := []string{"apple", "orange", "apple", "banana", "orange", "banana", "apple", "apple", "orange", "apple", "banana", "orange", "banana", "apple", "apple", "orange", "apple", "banana", "orange", "banana", "apple"}
        var num int = 0
        for _, _ = range arr {
        num++
        }
        fmt.Println(num) // 21, 与 cap()内建函数有着本质的区别
        fmt.Println(len(arr)) // 21
}

实例: 计算数组中元素的个数

package main
import (
"fmt"
)
func main() {
        arr := []string{"apple", "orange", "apple", "banana", "orange", "banana", "apple", "apple", "orange", "apple", "banana", "orange", "banana", "apple", "apple", "orange", "apple", "banana", "orange", "banana", "apple"}
        m := make(map[string]int)
        for _, v := range arr {
        if m[v] == 0 {
        m[v] = 1
        } else {
        m[v]++
        }
        }
        fmt.Println(m) //map[apple:9 orange:6 banana:6]
}

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码