Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Go语言入门基础

Go语言入门基础

作者头像
李海彬
发布于 2018-03-27 04:04:46
发布于 2018-03-27 04:04:46
68300
代码可运行
举报
文章被收录于专栏:Golang语言社区Golang语言社区
运行总次数:0
代码可运行

指针

Go 具有指针。 指针保存了变量的内存地址。

类型 *T 是指向类型 T的值的指针。其零值是 nil 。

  1. var p *int

复制代码

& 符号会生成一个指向其作用对象的指针。

  1. i := 42
  2. p = &i

复制代码

*符号表示指针指向的底层的值。

  1. fmt.Println(*p) // 通过指针 p 读取 i
  2. *p = 21         // 通过指针 p 设置 i

这也就是通常所说的“间接引用”或“非直接引用”。

与 C 不同,Go 没有指针运算。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import "fmt"

func main() {

    i, j := 42, 2701

    p := &i         // point to i

    fmt.Println(*p) // read i through the pointer

    *p = 21         // set i through the pointer

    fmt.Println(i)  // see the new value of i

    p = &j         // point to j

    *p = *p / 37   // divide j through the pointer

    fmt.Println(j) // see the new value of j

}

结构体

一个结构体( struct )就是一个字段的集合。(而 type 的含义跟其字面意思相符。)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import "fmt"

type Vertex struct {

    X int

    Y int

}

func main() {

    fmt.Println(Vertex{1, 2})

}

结构体字段

结构体字段使用点号来访问。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import "fmt"

type Vertex struct {

    X int

    Y int

}

func main() {

    v := Vertex{1, 2}

    v.X = 4

    fmt.Println(v.X)

}

结构体指针

结构体字段可以通过结构体指针来访问。 通过指针间接的访问是透明的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import "fmt"

type Vertex struct {

    X int

    Y int

}

func main() {

    v := Vertex{1, 2}

    p := &v

    p.X = 1e9

    fmt.Println(v)

}

结构体符文

结构体符文表示通过结构体字段的值作为列表来新分配一个结构体。 使用 Name: 语法可以仅列出部分字段。(字段名的顺序无关。) 特殊的前缀 & 返回一个指向结构体的指针。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import "fmt"

type Vertex struct {

    X, Y int

}

var (

    v1 = Vertex{1, 2}  // 类型为 Vertex

    v2 = Vertex{X: 1}  // Y:0 被省略

    v3 = Vertex{}      // X:0 和 Y:0

    p  = &Vertex{1, 2} // 类型为 *Vertex

)

func main() {

    fmt.Println(v1, p, v2, v3)

}

数组

类型 [n]T 是一个有 n 个类型为 T 的值的数组。

表达式

  1. var a [10]int

定义变量 a 是一个有十个整数的数组。

数组的长度是其类型的一部分,因此数组不能改变大小。这看起来是一个制约,但是请不要担心; Go 提供了更加便利的方式来使用数组。

切片(slice)

一个 slice 会指向一个序列的值,并且包含了长度信息。

[]T 是一个元素类型为 T 的 切片(slice)。

len(s)返回 slice s的长度。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import "fmt"

func main() {

    s := []int{2, 3, 5, 7, 11, 13}

    fmt.Println("s ==", s)

    for i := 0; i < len(s); i++ {

        fmt.Printf("s[%d] == %d\n", i, s[i])

    }

}

切片(slice)的切片

切片(slice)可以包含任意的类型,包括另一个 slice。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import (

    "fmt"

    "strings"

)

func main() {

    // Create a tic-tac-toe board.

    game := [][]string{

        []string{"_", "_", "_"},

        []string{"_", "_", "_"},

        []string{"_", "_", "_"},

    }

    // The players take turns.

    game[0][0] = "X"

    game[2][2] = "O"

    game[2][0] = "X"

    game[1][0] = "O"

    game[0][2] = "X"

    printBoard(game)

}

func printBoard(s [][]string) {

    for i := 0; i < len(s); i++ {

        fmt.Printf("%s\n", strings.Join(s[i], " "))

    }

}

对 slice 切片

slice 可以重新切片,创建一个新的 slice 值指向相同的数组。

表达式

  1. s[lo:hi]

表示从 lo 到 hi-1 的 slice 元素,含前端,不包含后端。因此

  1. s[lo:lo]

是空的,而

  1. s[lo:lo+1]

复制代码

有一个元素。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import "fmt"

func main() {

    s := []int{2, 3, 5, 7, 11, 13}

    fmt.Println("s ==", s)

    fmt.Println("s[1:4] ==", s[1:4])

    // 省略下标代表从 0 开始

    fmt.Println("s[:3] ==", s[:3])

    // 省略上标代表到 len(s) 结束

    fmt.Println("s[4:] ==", s[4:])

}

复制代码

构造 slice

slice 由函数 make 创建。这会分配一个全是零值的数组并且返回一个 slice 指向这个数组:

  1. a := make([]int, 5)  // len(a)=5

复制代码

为了指定容量,可传递第三个参数到 make:

  1. b := make([]int, 0, 5) // len(b)=0, cap(b)=5
  2. b = b[:cap(b)] // len(b)=5, cap(b)=5
  3. b = b[1:]      // len(b)=4, cap(b)=4

参考以下示例代码 -

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import "fmt"

func main() {

    a := make([]int, 5)

    printSlice("a", a)

    b := make([]int, 0, 5)

    printSlice("b", b)

    c := b[:2]

    printSlice("c", c)

    d := c[2:5]

    printSlice("d", d)

}

func printSlice(s string, x []int) {

    fmt.Printf("%s len=%d cap=%d %v\n",

        s, len(x), cap(x), x)

}

nil slice

slice 的零值是 nil 。

一个 nil 的 slice 的长度和容量是 0。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import "fmt"

func main() {

    var z []int

    fmt.Println(z, len(z), cap(z))

    if z == nil {

        fmt.Println("nil!")

    }

}

向 slice 添加元素

向 slice 的末尾添加元素是一种常见的操作,因此 Go 提供了一个内建函数 append 。 内建函数的文档对 append 有详细介绍。

  1. func append(s []T, vs ...T) []T

append 的第一个参数 s 是一个元素类型为 T 的 slice ,其余类型为 T 的值将会附加到该 slice 的末尾。

append 的结果是一个包含原 slice 所有元素加上新添加的元素的 slice。

如果 s 的底层数组太小,而不能容纳所有值时,会分配一个更大的数组。 返回的 slice 会指向这个新分配的数组。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import "fmt"

func main() {

    var a []int

    printSlice("a", a)

    // append works on nil slices.

    a = append(a, 0)

    printSlice("a", a)

    // the slice grows as needed.

    a = append(a, 1)

    printSlice("a", a)

    // we can add more than one element at a time.

    a = append(a, 2, 3, 4)

    printSlice("a", a)

}

func printSlice(s string, x []int) {

    fmt.Printf("%s len=%d cap=%d %v\n",

        s, len(x), cap(x), x)

}

复制代码

范围(range)

for 循环的 range 格式可以对 slice 或者 map 进行迭代循环。

当使用 for 循环遍历一个 slice 时,每次迭代 range 将返回两个值。 第一个是当前下标(序号),第二个是该下标所对应元素的一个拷贝。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ackage main

import "fmt"

var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}

func main() {

    for i, v := range pow {

        fmt.Printf("2**%d = %d\n", i, v)

    }

}

可以通过赋值给 _ 来忽略序号和值。

如果只需要索引值,去掉 “ , value ” 的部分即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import "fmt"

func main() {

    pow := make([]int, 10)

    for i := range pow {

        pow[i] = 1 << uint(i)

    }

    for _, value := range pow {

        fmt.Printf("%d\n", value)

    }

}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-07-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Java字符串拼接该如何选择呢?
在 Java 开发中,字符串拼接无处不在。但频繁使用+连接字符串,尤其是在循环或大量操作中,却是性能的隐形杀手!其根源在于String的不可变性—每次+操作都会在堆内存中创建新的String对象,旧的沦为待回收垃圾,内存和 CPU 开销巨大。
大王叫我来巡山、
2025/07/18
820
【专业技术】图解Java字符串不变性
1、声明一个字符串: String s = "abcd"; s中存储了一个指向堆内存字符串"adcd"的引用。 2、再声明一个字符串变量,同样指向堆内存的字符串"abcd"。 如上图所示,s和s2
程序员互动联盟
2018/03/12
6640
【专业技术】图解Java字符串不变性
3张图彻底了解Java中字符串的不变性
一旦一个string对象在内存(堆)中被创建出来,他就无法被修改。特别要注意的是,String类的所有方法都没有改变字符串本身的值,都是返回了一个新的对象。
Java团长
2018/08/06
2800
震惊,99.9% 的同学没有真正理解字符串的不可变性
稍有些基础的同学都知道 Java 中 String 字符串是“不可变”的,想要使用“可变字符串”可以使用 StringBuilder 和 StringBuffer 。
明明如月学长
2022/09/17
2830
震惊,99.9% 的同学没有真正理解字符串的不可变性
[Java 基础]字符串
静默虚空
2018/01/05
5390
你真的理解Java 字符串的不可变性吗?
下面看一个奇怪的现象:在程序一段程序的最后执行下面的语句居然打印了 “aw” 为什么?
明明如月学长
2021/08/31
4200
灵魂拷问:为什么 Java 字符串是不可变的?
在逛 programcreek 的时候,发现了一些精妙绝伦的主题。比如说:为什么 Java 字符串是不可变的?像这类灵魂拷问的主题,非常值得深思。
沉默王二
2019/11/14
6860
灵魂拷问:为什么 Java 字符串是不可变的?
基础面试,为什么面试官总喜欢问String?
关于 Java String,这是面试的基础,但是还有很多童鞋不能说清楚,所以本文将简单而又透彻的说明一下那个让你迷惑的 String
用户4172423
2019/09/08
3330
Python 字符串不可变性的优缺点
随着计算机技术的快速发展,越来越多的编程语言被发明出来,每种编程语言都有自己独特的特点和优势。以我经常使用python写爬虫为例,在 Python 中,字符串是不可变的,这意味着一旦字符串被创建,就不能被修改。这与其他一些编程语言(如 C++ 和 Java)不同,在这些语言中,字符串是可以被修改的。
华科云商小徐
2024/01/22
2490
聊一聊Java字符串的不可变
在 Java 开发中 String (字符串)对象是我们使用最频繁的对象,也是很重要的对象。正是使用得如此频繁,String 在实现层面上不断进行优化,从 Java6 到 Java7,再到 Java9 的新实现 ,都是为了提升 String 对象的性能,而其中不变的是 String 所生俱来的特性:不可变。本文主要聊一聊 String 的不可变,以及为什么存在的。
闻人的技术博客
2019/09/19
8260
聊一聊Java字符串的不可变
Java 中的final:不可变性的魔法之旅
在 Java 编程世界中,final 是一个引人注目的关键字,它赋予了变量、方法、类等各种元素不可变性。有些程序员将其视为一种约束,而另一些则将其视为一种保护措施。在这个博客中,我们将探索final的多种用法,从变量的不可变性到类的终结,了解其妙用。final是你代码的最后一道屏障,让我们一起发现它的力量。
一只牛博
2025/05/30
1170
一文读懂字符串String
String在java中特别常用,但小伙伴儿们对String真的彻底了解了吗?今天跟着小堂我一起盘它、弄懂它。
编程识堂
2023/05/24
6180
一文读懂字符串String
关于Java里面的字符串拼接,你了解多少?
字符串拼接是我们日常开发中很常见的操作,虽然常见,但要是使用不当的的话,很有可能让你的程序处理效率降低一大半,所以我们有必要来重新了解一下Java里面的字符串操作。
我是攻城师
2018/07/23
5740
关于Java里面的字符串拼接,你了解多少?
Java字符串
String s3=new String(a);//后续对字符数组的修改不会影响字符串
用户7886150
2021/02/02
8310
【Java】Java中String不可变性的底层实现
在Java编程中,String类的不可变性是一个被广泛讨论和利用的特性。这种不可变性使得String对象在创建后无法被修改,从而保证了程序的安全性和线程安全性。本文将深入探讨Java中String不可变性的底层实现原理,并讨论其对程序设计的影响。
人不走空
2024/03/07
1700
【Java】Java中String不可变性的底层实现
String字符串—详细总结
不可变的,每一次修改实际上生成新的字符串,并且该字符串的值是修改后的值。new String都是在堆上创建字符串对象
用户5325874
2020/01/16
4780
String字符串—详细总结
JAVA不可变类(immutable)机制与String的不可变性
不可变类:所谓的不可变类是指这个类的实例一旦创建完成后,就不能改变其成员变量值。如JDK内部自带的很多不可变类:Interger、Long和String等。 可变类:相对于不可变类,可变类创建实例后可以改变其成员变量值,开发中创建的大部分类都属于可变类。
lyb-geek
2018/12/26
1.7K0
字符串常量池 运行时常量池_常量池中的字符串是对象吗
关于String以及StringBuffer、StringBuilder的相关信息可以参考博主的另一篇文章:
全栈程序员站长
2022/09/18
3650
字符串常量池 运行时常量池_常量池中的字符串是对象吗
【面试题精讲】String 为什么是不可变的?
在 Java 中,String 是一个类,用于表示字符串。它是不可变的,即一旦创建就不能被修改。
程序员朱永胜
2023/10/09
2.3K0
JS中的非可变性
IMWeb前端团队
2017/12/29
1.2K0
推荐阅读
相关推荐
Java字符串拼接该如何选择呢?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档