Go 语言入门指南:基础语法和常用特性解析

文章目录

  • Hello,World
  • 变量、指针及赋值
    • 变量和常量
    • 指针
    • 赋值
  • 选择和循环
    • 选择
    • 循环
  • 基本数据类型
    • 整型
      • 整型的取值范围
    • 运算符
      • 二元运算符
      • 一元运算符
    • 浮点型
    • 复数和布尔类型
  • 字符串
    • rune
    • Unicode和UTF-8
    • 按字节访问
    • 按字符rune访问
    • 特点
  • 数组
    • 数组的定义
      • 1. 使用默认初始值
      • 2. 定义并初始化
      • 3. 省略数组长度
      • 4. 索引赋值初始化
    • 数组特点
    • 数组是默认按值传递
  • slice
    • 原型
    • 基本操作
    • append
    • slice的增长过程
    • copy
    • 其他
  • map
    • 基本操作
    • 特点
  • struct
  • 参考

Hello,World

package main

import "fmt"

func main(){
    fmt.Println("Hwllo,World!")
}
  • 1 1 1行是包的声明。本例中是main包,main包是每个项目的入口。
  • 3 3 3行,使用g键字import导入Go语言提供的标准包fmt。
  • 5 5 5行定义了一个函数,func是定义函数的关键字。
  • 6 6 6行使用fmt的Println函数输出字符串Hello,World!

注意:Go语言每行代码行尾是不需要加分号; 的,编译器会把换行符解析成分号,不能把函数的左扩号单独成行。

变量、指针及赋值

变量和常量

  • 变量声明使用var关键字
  • 常量声明使用const关键字
  • 变量的定义形式: var name 【类型】 = 【表达式】

注意:使用过程中,"类型"和"表达式"可以省略一个,但不能同时省略。Go语言能进行自动推导,根据类型推默认表达式,也能根据表达式推出类型。

类型默认值

  • 数字类型默认为0
  • 布尔类型默认为false
  • 字符串类型默认为""
  • 接口、slice、指针、map、通道、函数等类型默认值为nil

变量定义示例

// 省略类型
var m = 2

// 省略表达式
var n int

// 多个变量一起声明
var a, b, c int

// 多个变量一同通过表达式声明
var i, j, k = 1, "hello", true

常量定义示例

  • 常量的值是在程序编译的时候确定的,之后不可改变。
const LEN = 10

// 一次定义多个常量
const (
	SYS = "Windows"
	Type = "string"
)

:==

n1 := 10    // 正确   
n2 = 10     // 错误

var n3 int
n3 = 10     // 正确
  • := 是声明并赋值
  • =是给声明后的变量赋值

指针

  • Go语言支持指针,指针的默认初始值为nil

    var int x  
    p := &x    // & 为取地址符号。 p为指向x的整型指针
    *p = 1		
    fmt.Println(x)
    
  • Go也支持new函数

p := new(int)

赋值

  • =为赋值符号。等号左边是变量名,等号右边是表达式。

  • Go语言也提供了自增、自减和*=+=等先运算后赋值的操作

    m := 1
    m++    	// 相当于 m = m + 1
    m -= 1  // 相当于 m = m - 1
    
  • Go同样支持多重赋值

    m := 2
    n := 3
    m,n = n,m  // 实现交换m,n的值
    
    var a, b, c int // a, b, c 同时声明 
    a,b,c = 1,2,3  	// a,b, c 同时赋值
    

选择和循环

选择

  • Go语言也提供if elseswitch语句

  • switch语句的每个case不需要额外的break

    if expression == true {
        fmt.Println("条件成立1")
    }
    
    if expression == false {
        fmt.Println("条件成立2")
    }
    

循环

  • Go语言只提供for关键字,没有while等其他关键字。

for形式

// 一般形式
for i := 0; i < 100; i++ {
    
}

// 相当于 while
for {
    
}

// 相当于 do ... while
for ok := true; ok; ok = expression{
    
}

// for循环也支持range函数 
arr := []int{1, 2, 3, 4}    // 定义切片slice,类似c的数组
for i, v : range arr{
    fmt.Println("index: ",i, "value: ", v)
}

基本数据类型

整型

  • int8int8int6int32分别对应8、16、32、64位整数。

整型的取值范围

  • 整型分带符号整数和无符号整数。int为带符号整型,uint为无符号类型。

    // 带符号整数
    int8  (-128 ~ 127)
    int16 (-32768 ~ 32767)
    int32 (-2,147,483,648 ~ 2,147,483,647)
    int64 (-9,233,372,036,854,775,808 ~ 9,233,372,036,854,775,807)
    
    // 无符号整数
    unit8  (0 ~ 255)
    unit16 (0 ~ 65,535)
    unit32 (0 ~ 4,294,967,295)
    unit64 (0 ~ 18,446,744,073,709,551,615)
    

运算符

二元运算符

  • 二元运算符包括算术运算、逻辑运算和比较运算

运算符优先级从上到下的递减顺序排列:

*	/	%	<< 	>>	&	&^
+	-	|	^
==	!=	<	<=	>	>=
&&
||
  • 同一优先级,使用左优先结合规则。

一元运算符

  • 一元运算符包括正负号、bit位运算

    &	与 AND
    |	或 OR
    ^	异或 XOR
    &^ 	位清空 (AND NOT)
    << 	左移
    >> 右移
    
  • 左移<<:左移运算用零填充右边空缺的bit位

  • 右移>>:无符号数右移运算用0填充左边空缺的bit位,有符号数的右移运算用符号位的值填充左边空缺的bit位。

浮点型

  • 浮点型分float32float64。推荐使用float64

  • float32表示小数可能会出现精度丢失。下面给出示例。

    package main
    
    import "fmt"
    
    func main() {
       	var f1 float32 = 9.90
    	fmt.Println(f1*100)
    	
    	var f2 float64 = 9.90
    	fmt.Println(f2*100)
    }
    
    /* output
    989.99994
    990
    */
    

复数和布尔类型

复数类型

  • 复数分为complex64complex128,它们分别有float32float64组成。

  • 复数由实部和虚部组成,内置的realimag函数用于获取复数的实部和虚部

    var a complex128 = complex(2,3) // 2+3i
    fmt.Println(real(a)) // 2
    fmt.Println(imag(a)) // 3
    

布尔类型

  • bool的值用true和false表示

  • Go语言的布尔类型没有强制类型转换,无法把0转换成false

    var b bool
    b = 0	// 报错
    

字符串

  • Go语言字符串按字节存储,不同字符占用不同数目的字节。

  • 字符串的字符按unicode编码存储,不同的字符按1~4个字节存储。其中,中文汉字占用3个字节,英文占用1个字节。

  • 字符串索引访问是按字节访问的,而不是字符。

img

rune

  • unicode通常用4个字节来表示,对应Go语言的字符rune占4个字节

  • rune类型是一个衍生类型,在内存里面使用int32类型的4各字节存储

    type rune int32
    

Unicode和UTF-8

  • Unicode支持超过一百种的语言和十万字符的码点。

  • UTF-8是Unicode标准的一种实现。

  • UTF-8特点:

    • 字符长度可变,长度1到4字节不等。
    • 第一个bit为0,那么长度为1字节,使用剩余7位存放字符,正好能覆盖ASCII码字符集。
    • 前两位是10,则表示长度为两个字节,第二个字节以0开头。
    • 对于三个字节的UTF-8码。这三个字节分别是110、10和0。

按字节访问

package main

import "fmt"

func main() {
	var s = "嘻哈china"
	for i:=0;i<len(s);i++ {
		fmt.Printf("%d %x ", i, s[i])
	}
 
}

-----------
0 e5 1 98 2 bb 3 e5 4 93 5 88 6 63 7 68 8 69 9 6e 10 61

按字符rune访问

package main

import "fmt"

func main() {
	var s = "嘻哈china"
	for codepoint, runeValue := range s {
		fmt.Printf("%d %d ", codepoint, int32(runeValue))
	}
}

-----------
0 22075 3 21704 6 99 7 104 8 105 9 110 10 97

对字符串进行range遍历,每次迭代出两个变量codepoint和runeValue。

codepoint表示字符起始位置,runeValue表示对于的unicode编码(类型是rune)

特点

  • 字符串是只读的,不支持按索引修改。
  • 字符串支持切片成子串

字节数组和字符串的转换

借助[]byte()string()即可

var s1 = "hello world"     
var b = []byte(s1)     // 字符串转字节数组
var s2 = string(b)	   // 字节数组转字符串

/*
b = [104 101 108 108 111 32 119 111 114 108 100]
s2 = hello world
*/

数组

  • 在Go语言中,数组的使用频率并不高,因为数组长度不可变,很多时候都是使用slice(切片)。slice比数组更灵活,长度是可变的。

数组的定义

1. 使用默认初始值

var a [3]int
  • 定义了长度为3的整型数组,三个元素都是默认初始值0

2. 定义并初始化

var b [3]int = [3]int{1, 2, 3}
var b = [3]int{1, 2, 3}

3. 省略数组长度

c := [...]int{1, 2, 3}
  • 数组长度由后面元素的个数决定。这里数组的长度为3

4. 索引赋值初始化

d := [...]int{4, 4:1, 1:2}

// d : {4, 2, 0, 0, 1}
  • 并没有给所有的元素赋值,而且赋值使用了index:value的方式。4:1的意思是给下标为4的元素赋值为1,。
  • 数组长度根据最大下标确定。

数组特点

  • [3]int[4]int是两种不同的数据类型,这两种不同的数组在编译时就已经确定。把[4]int类型的变量赋值给[3]int类型的变量会报错。
  • Go语言数组长度是数组的一部分,并非向C语言那样只存储数组的地址
  • 在分配内存底层空间时,数组的元素是紧挨着分配到固定位置的,这也是数组长度不可变的原因。

数组是默认按值传递

  • Go语言数组是传递值的,不同于其他语言的数组都是传递引用的。
  • 值传递涉及数组的拷贝,会浪费性能,但形参数组的修改不会影响原数组。

给出一个实例,修改数组的0索引位置的元素

一种是直接传数组,此时是值传递。另一种是传数组地址,此时是引用传递(指针)。

package main

import "fmt"

func main() {
	var a [3]int = [3]int{1, 2, 3}
    
	change_arr_by_value(a)
	fmt.Println(a[0]) // 1 按值传递,修改失败

	change_arr_by_reference(&a)
	fmt.Println(a[0]) // 999 按索引传递,修改成功
}

func change_arr_by_value(arr [3]int) {
	arr[0] = 999
}

func change_arr_by_reference(arr *[3]int) {
	arr[0] = 999
}

slice

  • slice(切片)是一个拥有相同类型元素的可变长序列,且slice定义和数组的定义很像。

原型

type SliceHeader struct {
	Data uintptr	// 指针
	Len int			// 长度
	Cap int			// 容量
}

说明

  • 指针指向slice开始访问的第一个元素
  • 长度是切片的长度,及元素个数
  • 容量是切片能访问的最大元素个数。slice的容量大于等于silice的长度

切片的底层是数组,Go语言的切片对应着底层数组。一个底层数组可以对应多个slice。

基本操作

定义

s := []int{1, 2, 3, 4, 5}

如果在方括号中指定了长度或写入省略号,那就是一个数组。

ss := make([]int, 10)

make函数定义了[ ]int类型的切片,长度为10,元素默认值为0

释放slice

ss = nil

如果将slice赋值为nil,垃圾回收机制将会回收slice的空间。

获取长度和容量

len(slice)
cap(slice)

切片

  • 切片s[i:j]是左闭右开,索引区间是[i, j)
s := []int{0, 1, 2, 3, 4, 5}
s[0:3] // {0, 1, 2}
  • 左边界i不写,默认是0。右边界j不写,默认是切片的容量cap(slice)。
  • s[:]是整个切片。

数组的切片

  • 对数组切片的修改会影响原数组。
a := [...]int{1, 2, 3, 4, 5}
ss := a[1:3]
ss[0] = 99
ss[1] = -99

fmt.Println(ss)  // [99, -99]
fmt.Println(a) 	 // [1, 99, -99, 4, 5]

slice默认是引用传递

append

  • slice的长度是动态的。append可以在原来的切片上插入元素,可以在开头、结尾、指定位置插入元素或其他slice。数组不能直接插入,要转换成切片才能添加。
s = []int{1, 2, 3}			// 定义切片
arr = [3]int{66, 77, 88}	// 定义数组

头插

ss = append(a[:], ss...)
ss = append([]int{1}, ss...)

注意:ss...意思是把切片ss,拆解成一个个元素。之后将依次插入。 a[:]是取数组的切片。

尾插

ss = append(ss, 1)
ss = append(ss, a[:]...)

任意位置插入

  • 演示在ss的索引为1的位置插入
ss = append(ss[:1], append(a[:], ss[1:]...)...)

slice的增长过程

切片的底层是数组,如果使用append函数向切片中添加元素是,实际上是把元素放到切片的底层数组。

如果底层数组满了,没有空间,这时再向切片添加元素,Go只能创建一个更大的新数组,将原来的数组复制到新数组,并把新数组作为切片的底层数组。

代码演示

s1 := []int{1, 2, 3}
fmt.Printf("长度:%d,容量:%d,数组地址:%p\n", len(s1), cap(s1), s1)
s1 = append(s1, 4)
fmt.Printf("长度:%d,容量:%d,数组地址:%p\n", len(s1), cap(s1), s1)
s1 = append(s1, 5)
fmt.Printf("长度:%d,容量:%d,数组地址:%p\n", len(s1), cap(s1), s1)
s1 = append(s1, 6)
fmt.Printf("长度:%d,容量:%d,数组地址:%p\n", len(s1), cap(s1), s1)
s1 = append(s1, 7)
fmt.Printf("长度:%d,容量:%d,数组地址:%p\n", len(s1), cap(s1), s1)
s1 = append(s1, 8)
fmt.Printf("长度:%d,容量:%d,数组地址:%p\n", len(s1), cap(s1), s1)


/*output
	长度:3,容量:3,数组地址:0xc00001e0c0
    长度:4,容量:6,数组地址:0xc00001a120
    长度:5,容量:6,数组地址:0xc00001a120
    长度:6,容量:6,数组地址:0xc00001a120
    长度:7,容量:12,数组地址:0xc00005c060
    长度:8,容量:12,数组地址:0xc00005c060
*/

切片变换过程

img

copy

  • 切片元素的赋值可利用copy函数
a1 := []{1,1,1,1,1}
b1 := []{-1,-1,-1}
copy(a1, b1)  // 将 b1 复制到 a1
// a1 : [-1,-1,-1,1,1]

a2 := []{2,2,2,2,2}
b2 := []{-2,-2,-2}
copy(b2, a2)  // 将 b1 复制到 a1
// b2 : [2,2,2]

注意:要理解复制到的含义。

  • copy函数只涉及元素值的拷贝,不涉新空间的创造

  • copy的两个参数必须是slice,不能是数组

其他

slice是通过指向底层数组来存储数据,而且可能有多个slice指向同一个底层数组。如果有任一切片指向这个数组,底层数组就因处于使用状态而无法被删除。

极端情况,很小的切片指向很大底层数组,会造成空间的浪费。

map

  • map(映射)是Go语言提供的key-value(键值对)形式的无序集合。

  • map的底层是Hash(哈希)表。

  • 键值对的键有唯一性的要求,通过键来获取值和更新值。

定义形式

map[k]v

  • k是键,同一mao中所有的key是同一数据类型,而且必须能进行==的比较运算 。
  • boll类型作为k并不灵活,而浮点型作为k,可能会因为精度问题而导致异常。

基本操作

创建map

// 方式一
m1 := make(map[string]int)

// 方式二
m2 := map[string]int{
    "k1" : 11,
    "k2" : 22,
}

访问元素

map[k], 比如val,ok = m2["k1"]。根据key找val,如果key不存在,ok=false。

添加元素

map[key] = value

注意:key如果存在,则用value更新值。如果不存在,则添加key-value对。

删除元素

delete(map, k),比如delete[m2, "k2"]

注意:delete函数删除不存在的key时,不会出错。

遍历map

for k, v := range m2 {
    fmt.Println(k, v)
}

特点

  • map在元素赋值之前必须初始化。使用上面两种方式均可。如果只声明map,使用则会出错。

    var m1 map[string]int
    m1["k1"] = 12  // error: assignment to nil map 
    
  • map的默认初始值是nil,未初始化的map是nil。尽管如此,未初始化的map执行删除元素、len操作、range操作或查找元素时都不会报错。但未初始化之前进行元素赋值操作会出错。

struct

  • struct是复合类型,而非引用类型。复合类型是值传递,而引用类型是引用传递。

结构体定义

type Person struct {
	name string
	gender int
	age int
}

var p1 Person

p2 := Person{"Jack", 1, 18}

p3 := Person{name:"Scott", gender:1, age:18}

注意:struct成员的可见性是通过首字母大小写控制,首字母小写仅本报可见,首字母大写则包外也可访问。

成员访问

p3.name

结构体指针

var pp *Person

注意:结构体指针必须初始化后才可以使用,因为如果仅仅声明结构体指针类型变量,其默认值初始值是nil。

pp := new(Person),创建指向Person结构体的指针pp。

pp.name = "Json",结构体指针访问成员也是直接.运算符,这是Go的语法糖。

make和new

make函数用于slice、map和chan进行内存分配,它返回的不是指针,而是上面三个类型中的某一个类型本身。

new函数返回初始化的类型对应的指针,new函数主要用于struct初始化中,其他场景英语较少。

参考

《快学 Go 语言》第 7 课

重学Go语言 | Slice全面讲解

Go微服务实战

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/49164.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

13.4.2 【Linux】sudo

相对于 su 需要了解新切换的使用者密码 &#xff08;常常是需要 root 的密码&#xff09;&#xff0c; sudo 的执行则仅需要自己的密码即可。sudo 可以让你以其他用户的身份执行指令 &#xff08;通常是使用 root 的身份来执行指令&#xff09;&#xff0c;因此并非所有人都能够…

Verilog语法学习——LV1_四选一多路器

LV1_四选一多路器 题目来源于牛客网 [牛客网在线编程_Verilog篇_Verilog快速入门 (nowcoder.com)](https://www.nowcoder.com/exam/oj?page1&tabVerilog篇&topicId301) 题目 制作一个四选一的多路选择器&#xff0c;要求输出定义上为线网类型 状态转换&#xff1a;…

将Parasoft和ChatGPT相结合会如何?

ChatGPT是2023年最热门的话题之一&#xff0c;是OpenAI训练的语言模型。它能够理解和生成自然语言文本&#xff0c;并接受过大量数据的训练&#xff0c;包括用各种编程语言编写的许多开源项目的源代码。 软件开发人员可以利用大量的知识库来协助他们的工作&#xff0c;因为它具…

迁移学习、微调、计算机视觉理论(第十一次组会ppt)

@TOC 数据增广 迁移学习 微调 目标检测和边界框 区域卷积神经网络R—CNN

Kafka-配置Kerberos安全认证(JDK8、JDK11)

一、相关配置 1、JAAS 配置文件 KafkaClient {com.sun.security.auth.module.Krb5LoginModule requireduseKeyTabtruestoreKeytrueserviceName"kafka"keyTab"D:/code/demo/conf/kafka.service.keytab"principal"kafka/hdp-1"; }; 2、keytab 文…

3d软件动物生活习性仿真互动教学有哪些优势

软体动物是一类广泛存在于海洋和淡水环境中的生物&#xff0c;其独特的形态和生活习性给学生带来了新奇和有趣的学习主题&#xff0c;为了方便相关专业学科日常授课教学&#xff0c;web3d开发公司深圳华锐视点基于真实的软体动物&#xff0c;制作软体动物3D虚拟展示系统&#x…

在CSDN学Golang云原生(Kubernetes声明式资源管理Kustomize)

一&#xff0c;生成资源 在 Kubernetes 中&#xff0c;我们可以通过 YAML 或 JSON 文件来定义和创建各种资源对象&#xff0c;例如 Pod、Service、Deployment 等。下面是一个简单的 YAML 文件示例&#xff0c;用于创建一个 Nginx Pod&#xff1a; apiVersion: v1 kind: Pod m…

瓦瑟斯坦距离、收缩映射和现代RL理论

Wasserstein Distance, Contraction Mapping, and Modern RL Theory | by Kowshik chilamkurthy | Medium 一、说明 数学家们在考虑一些应用的情况下探索的概念和关系 - 几十年后成为他们最初从未想象过的问题的意想不到的解决方案。 黎曼的几何学只是出于纯粹的原因才被发现的…

动静态网页、Django创建表关系、Django框架的请求生命周期流程图

一、request对象的几个方法 在视图函数中写方法的时候&#xff0c;都会有一个形参requestdef index(request):passrequest.method # GET POST request.GET.get() # 它获取最后一个元素值 request.GET.getlist() # 获取到所有的request.POST.get() # 它获取最后一个元素值 req…

哈工大计算机网络课程局域网详解之:无线局域网

哈工大计算机网络课程局域网详解之&#xff1a;无线局域网 文章目录 哈工大计算机网络课程局域网详解之&#xff1a;无线局域网IEEE 802.11无线局域网802.11体系结构802.11&#xff1a;信道与AP关联 本节介绍一下平时经常使用的一个无线局域网技术&#xff0c;也就是通常我们使…

Vue2基础五、工程化开发

零、文章目录 Vue2基础五、工程化开发 1、工程化开发和脚手架 &#xff08;1&#xff09;开发 Vue 的两种方式 核心包传统开发模式&#xff1a;基于 html / css / js 文件&#xff0c;直接引入核心包&#xff0c;开发 Vue。工程化开发模式&#xff1a;基于构建工具&#xf…

CSS Flex 笔记

1. Flexbox 术语 Flex 容器可以是<div> 等&#xff0c;对其设置属性&#xff1a;display: flex, justify-content 是沿主轴方向调整元素&#xff0c;align-items 是沿交叉轴对齐元素。 2. Cheatsheet 2.1 设置 Flex 容器&#xff0c;加粗的属性为默认值 2.1.1 align-it…

Windows 找不到文件‘chrome‘。请确定文件名是否正确后,再试一次

爱像时间&#xff0c;永恒不变而又短暂&#xff1b;爱像流水&#xff0c;浩瀚壮阔却又普普通通。 Windows 找不到文件chrome。请确定文件名是否正确后&#xff0c;再试一次 如果 Windows 提示找不到文件 "chrome"&#xff0c;可能是由于以下几种原因导致的&#xff1…

Unity下如何实现低延迟的全景RTMP|RTSP流渲染

技术背景 Unity3D可以用于创建各种类型的的应用程序&#xff0c;包括虚拟现实、培训模拟器等。以下是一些可以使用Unity3D全景播放的场景&#xff1a; 虚拟现实体验&#xff1a;全景视频可以用来创建逼真的虚拟环境&#xff0c;使用户能够感受到身临其境的感觉&#xff1b;培…

LeetCode|backtracking|review:40. 131. 93. 47. 332. | 37. Sudoku Solver

复习&#xff1a; 40. Combination Sum II [1,1,2,3]中&#xff0c;答案里有[1,1,2], 但是不能有两个[1,2,3] 131. Palindrome Partitioning 每个for都是在给定的start之后找一个palindrome。当start 93. Restore IP Addresses forloop每次loop都是在给定的start的后三个数…

干货 | 5个经典的模拟电路解析,电子人必看!

干货 | 5个经典的模拟电路解析&#xff0c;电子人必看&#xff01; 作为一个电子人&#xff0c;我们平时需要和不同的电路接触&#xff0c;但有一些电路图是经典的&#xff0c;值得我们永远记住。一、自举电路 此电路用在各种ADC之前的采样电路&#xff0c;可以让ADC实现轨到轨…

给APK签名—两种方式(flutter android 安装包)

前提&#xff1a;给未签名的apk签名&#xff0c;可以先检查下apk有没有签名 通过命令行查看&#xff1a;打开终端或命令行界面&#xff0c;导入包含APK文件的目录&#xff0c;并执行以下命令&#xff1a; keytool -printcert -jarfile your_app.apk 将 your_app.apk替换为要检查…

《2023中国开发者调查报告》探索2023中国开发者的技术创新与挑战:AIoT、云原生、国产数据库等领域的发展与前景

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

[论文阅读笔记24]Social-STGCNN: A Social Spatio-Temporal GCNN for Human Traj. Pred.

论文: 论文地址 代码: 代码地址 作者在这篇文章中直接用GNN对目标的轨迹时空特征进行建模, 并用时序CNN进行预测, 代替了训练难度较大和速度较慢的RNN类方法. 0. Abstract 行人轨迹预测是一个比较有挑战性的任务, 有着许多的应用. 一个行人的轨迹不仅是由自己决定的, 而且受…

[JavaScript游戏开发] 绘制冰宫宝藏地图、人物鼠标点击移动、障碍检测

系列文章目录 第一章 2D二维地图绘制、人物移动、障碍检测 第二章 跟随人物二维动态地图绘制、自动寻径、小地图显示(人物红点显示) 第三章 绘制冰宫宝藏地图、人物鼠标点击移动、障碍检测 文章目录 系列文章目录前言一、本章节效果图二、介绍2.1、准备地图素材2.2、封装地图上…