当前位置: 首页 > news >正文

【启程Golang之旅】掌握Go语言数组基础概念与实际应用

欢迎来到Golang的世界!在当今快节奏的软件开发领域,选择一种高效、简洁的编程语言至关重要。而在这方面,Golang(又称Go)无疑是一个备受瞩目的选择。在本文中,带领您探索Golang的世界,一步步地了解这门语言的基础知识和实用技巧。

目录

初识数组

二维数组

slice切片

map映射


初识数组

        在Go语言中,数组是一种固定长度的、包含相同类型元素的序列。数组的长度是类型的一部分,因此[5]int和[10]int是两种不同的类型。数组在Go中是值类型,这意味着当你传递一个数组到函数或将其赋值给另一个变量时,实际上是在复制整个数组的内容。

在Go语言中数组的内存分配是静态的,并且是在编译时确定的。由于数组的长度是类型的一部分,所以不同长度的数组在内存中的表示和占用是不同的。以下是关于Go语言中数组内存分析的代码示例:

package main
import "fmt"
func main() {// 声明数组var arr [3]int16// 获取数组长度fmt.Println(len(arr)) // 3// 打印数组fmt.Println(arr) // [0 0 0]// 证明arr中存储的是地址值fmt.Printf("arr的地址为:%p \n", &arr) // arr的地址为:0xc0000100b0// 第一个空间地址fmt.Printf("arr[0]的地址为:%p \n", &arr[0]) // arr[0]的地址为:0xc0000100b0// 第二个空间地址fmt.Printf("arr[1]的地址为:%p \n", &arr[1]) // arr[1]的地址为:0xc0000100b2// 第三个空间地址fmt.Printf("arr[2]的地址为:%p \n", &arr[2]) // arr[2]的地址为:0xc0000100b4
}

因为int占两个字节,所以地址值之间间隔为2,如下是图例解释:

接下来我们通过用户终端输入的方式,将数据存入数组当中,然后遍历数组,将数据打印出来:

package main
import "fmt"
func main() {// 定义数组var scores [5]int// 将成绩存入数组for i := 0; i < len(scores); i++ {fmt.Printf("请录入第%d个学生的成绩", i+1)fmt.Scanln(&scores[i])}// 展示一下录入学生的成绩:(对数组进行遍历)for i := 0; i < len(scores); i++ {fmt.Printf("第%d个学生的成绩为:%d \n", i, scores[i])}// 求和sum := 0for i := 0; i < len(scores); i++ {sum += scores[i]}// 平均数avg := sum / len(scores)// 输出fmt.Printf("成绩的总和为:%v, 成绩的平均数为:%v", sum, avg)
}

最终呈现的效果如下所示:

当然这里也可以采用for range的方式,for range结构是go语言中特有的一种迭代结构,在许多情况下都非常有用,for range可以遍历数组、切片、字符串、map及通道,示例代码如下,最终也能得到上面图片的结果:

func main() {// 定义数组var scores [5]int// 将成绩存入数组for i := 0; i < len(scores); i++ {fmt.Printf("请录入第%d个学生的成绩", i+1)fmt.Scanln(&scores[i])}// 展示一下录入学生的成绩:(对数组进行遍历) for range方式for key, value := range scores {fmt.Printf("第%d个学生的成绩为:%d \n", key+1, value)}
}

数组可以有多种书写方式,如下可以看到我们数组的书写方式:

package main
import "fmt"
func main() {// 数组的几种书写方式// var scores [5]int = [5]int{94, 98, 89, 80, 90} // 基本写法// var scores = [5]int{94, 98, 89, 80, 90} // 省略类型和长度//var scores = [...]int{2: 66, 0: 33, 1: 99, 3: 88} // 确定数组下标对应的数值scores := []int{94, 98, 89, 80, 90} // 使用切片(slice)语法(这在Go中更为常见)sum := 0for i := 0; i < len(scores); i++ {// 求得成绩的总值sum += scores[i]}// 平均数avg := sum / len(scores)// 输出fmt.Printf("成绩的总和:%v, 成绩的平均数为:%v\n", sum, avg)
}

在go语言中,关于数组还有以下注意事项,这里做一个简单的概述:

长度属于类型的一部分:

func main() {// 定义一个数组var arr1 = [3]int{1, 2, 3}fmt.Printf("数组的类型为:%T", arr1) // [3]intvar arr2 = [6]int{3, 4, 5, 6, 7, 8}fmt.Printf("数组的类型为:%T", arr2) // [6]int
}

数组属于值类型,在默认情况下是值传递,因此会进行值拷贝,如下图所示我对数组的值进行修改是修改了arr的值,并不是arr3的:

如想在其它函数中去修改原来的数组,可以使用引用传递(指针方式):

package main
import "fmt"
func test(arr *[3]int) {(*arr)[0] = 7
}func main() {var arr3 = [3]int{3, 6, 9}test(&arr3)       // 传入arr3数组的地址fmt.Println(arr3) // [7 6 9]
}

二维数组

在Go语言中,二维数组(也称为矩阵)是一个数组,其中每个元素都是另一个数组。这意味着你可以有两个维度来索引数据:第一个维度表示行,第二个维度表示列。示例代码如下:

func main() {var arr1 [2][3]int = [2][3]int{{1, 2, 3}, {4, 5, 6}}fmt.Println(arr1) // [[1 2 3] [4 5 6]]
}

在下面的例子中,array2D 是一个5行3列的二维整型数组,这里可以通过array2D[row][column]的方式来访问或修改数组中的元素:

func main() {// 声明一个5行3列的二维整型数组var array2D [5][3]int// 初始化时直接赋值array2D = [5][3]int{{1, 2, 3},{4, 5, 6},{7, 8, 9},{10, 11, 12},{13, 14, 15},}// 访问二维数组中的元素fmt.Println(array2D[2][1]) // 输出: 8
}

如果想对二维数组进行遍历的话,需要用到双层for循环,这里进行一个简单的示例:

package main
import "fmt"
func main() {// 定义二维数组var arr = [3][3]int{{1, 4, 7}, {2, 5, 8}, {3, 6, 9}}fmt.Println(arr)fmt.Println("---------------")// 方式1:普通for循环for i := 0; i < len(arr); i++ {for j := 0; j < len(arr[i]); j++ {fmt.Print(arr[i][j], "\t")}fmt.Println()}// 方式2:for range循环for key, value := range arr {for k, v := range value {fmt.Printf("arr[%v][%v] = %v \t", key, k, v)}fmt.Println()}
}

最终达到的效果如下所示:

slice切片

在Go语言中,切片(slice)是对数组的一个连续片段的引用,它本身并不包含数组的数据,而是包含了对底层数组的引用、长度以及容量。切片提供了一种灵活、方便且高效的方式来操作数组的一个子集,是一种建立在数组类型之上的抽象,它构建在数组之上并且提供更强大的能力和便捷,如下代码给出切片的示例:

package main
import "fmt"
func main() {// 定义数组var intarr [6]int = [6]int{3, 6, 7, 1, 2, 3}// 定义切片 slice [1:3]表示切出的一段片段,索引从1开始,到3结束slice := intarr[1:3]// 输出数组fmt.Println("intarr: ", intarr) // intarr:  [3 6 7 1 2 3]// 输出切片fmt.Println("slice: ", slice) // slice:  [6 7]// 切片元素个数fmt.Println("slice的元素个数: ", len(slice)) // slice的元素个数:  2// 获取切片的容量,容量可以动态变化fmt.Println("slice的容量: ", cap(slice)) // slice的容量:  5
}

切片由3个字段的数据结构组成:指向底层数组的指针、切片的长度、切片的容量

切片的创建:在Go语言中,make 是一个内置函数,用于动态地分配并初始化对象,这些对象包括切片(slices)、映射(maps)和通道(channels)。特别是当我们谈论切片时,make 是创建它们的主要方式,使用 make 创建切片的基本语法如下所示:

slice := make([]T, length, capacity)

这里通过如下代码进行简单示例,在下面的示例中,我们创建了一个整数类型的切片 slice,其长度为 3,容量为 5。这意味着切片当前可以存储 3 个整数,但底层数组的大小为 5,因此将来可以在不重新分配内存的情况下向切片添加最多 2 个额外的整数。

func main() {// 定义切片:make函数的三个参数:1、切片类型 2、切片长度 3、切片容量slice := make([]int, 3, 5)fmt.Println(slice)               // [0 0 0]fmt.Println("切片的长度", len(slice)) // 切片的长度 3fmt.Println("切片的容量", cap(slice)) // 切片的容量 5
}

make底层创建一个数组,对外不可见,所以不可以直接操作这个数组,要通过slice去间接的访问各个元素,不可以直接对数组进行维护/操作。

切片的遍历:对切片的遍历可以采用如下的方式进行:

func main() {// 定义切片:make函数的三个参数:1、切片类型 2、切片长度 3、切片容量slice := make([]int, 4, 20)slice[0] = 66slice[1] = 77slice[2] = 88slice[3] = 99// 方式1:普通for循环,遍历切片for i := 0; i < len(slice); i++ {fmt.Printf("slice[%v] = %v \t", i, slice[i])}fmt.Println("\n------------------------")// 方式2:for range循环,遍历切片for index, value := range slice {fmt.Printf("slice[%v] = %v \t", index, value)}
}

最终呈现的效果如下所示:

切片的注意事项

1)切片定义后不可以直接使用,需要让其引用到一个数组,或者make一个空间供切片来使用

2)切片使用不能越界

3)切片的简写方式

var slice = arr[0:end] ----》 var slice = arr[:end]

var slice = arr[start:len(arr)] ----》 var slice = arr[start:]

var slice = arr[0:len(arr)] ----》 var slice = arr[:]

4)切片可以继续切片

5)切片可以动态增长

func main() {// 定义数组var intarr [6]int = [6]int{1, 4, 7, 3, 6, 9}// 定义切片var slice []int = intarr[1:4] // 4 7 3fmt.Println(len(slice))       // 3slice2 := append(slice, 88, 50)fmt.Println(slice2) // [4 7 3 88 50]fmt.Println(slice)  // [4 7 3]/* 底层原理1.底层追加元素的时候对底层数组扩容,老数组扩容为新数组2.创建一个新数组,将老数组中的 4,7,3 拷贝到新数组中,在新数组中追加 88,503.slice2底层数组的指向 指向的是新数组4.往往我们在使用追加的时候其实想要做的效果是给slice追加元素,而不是给底层数组追加元素*/slice = append(slice, 10)fmt.Println(slice) // [4 7 3 10]// 底层的新数组不能直接维护,因为slice2底层数组的地址已经变了,所以我们需要重新创建一个新的切片,通过切片间接操作slice3 := []int{99, 44}slice = append(slice, slice3...)fmt.Println(slice) // [4 7 3 10 99 44]
}

6)切片的拷贝

func main() {// 定义数组var a []int = []int{1, 4, 7, 3, 6, 9}// 再定义一个切片var b []int = make([]int, 10)// 拷贝copy(b, a)     // 将a中的值拷贝到b中fmt.Println(b) // [1 4 7 3 6 9 0 0 0 0]
}

map映射

在Go语言中,map 是一种内置的数据结构,用于存储键值对(key-value pairs)的集合。map 提供了根据键来存储、检索和删除值的能力,使得在Go中处理关联数据变得非常方便,接下来通过如下代码示例进行演示:

func main() {// 定义map变量/*map: 这表示我们正在声明一个 map 类型的变量[int]string: 这部分定义了 map 的键和值的类型具体来说,int 是键的类型,而 string 是值的类型这意味着你可以将整数用作键,并将字符串作为与这些键相关联的值存储在 map 中*/var a map[int]string// 只声明map内存是没有分配空间的,需要使用make函数初始化分配空间a = make(map[int]string, 10) // map可以存放10个键值对,10可以不传,默认会分配一个起始大小// 初始化mapa[3] = "one"a[1] = "two"a[2] = "three"// 输出集合fmt.Println(a) // map[1:one 2:two 3:three]
}

注意:map集合在使用前一定要make;map的key是按照从小到大排序;key值不能重复,如果重复后一个value会对前一个进行覆盖,value是可以重复的;make函数的第二个参数size可以省略,默认就分配一个内存

map的创建方式可以通过如下的操作进行:

func main() {// map的创建方式// 方式1a := make(map[int]string)a[2020] = "张三"a[2019] = "李四"fmt.Println(a) // map[2019:李四 2020:张三]// 方式2b := map[int]string{2019: "张三",2020: "李四",}b[2018] = "王五"fmt.Println(b) // map[2018:王五 2019:张三 2020:李四]
}

当然我们也可以通过map对数值进行增删改查的操作,具体如下:

增加和更新操作:map["key"]= value 一》如果key还没有,就是增加,如果key存在就是修改。

func main() {a := make(map[int]string)// 增加操作a[2020] = "张三"a[2019] = "李四"// 修改操作a[2020] = "张三!!!"fmt.Println(a) // map[2019:李四 2020:张三!!!]
}

删除操作:delete(map,“key"),delete是一个内置函数,如果key存在,就删除该key-value,如果k的y不存在,不操作,但是也不会报错。

func main() {a := make(map[int]string)// 增加操作a[2020] = "张三"a[2019] = "李四"// 删除操作delete(a, 2019)fmt.Println(a) // map[2020:张三]
}

清空操作:如果我们要删除map的所有key,没有一个专门的方法一次删除,可以遍历一下key,逐个删除;或者map=make(),make一个新的,让原来的成为垃圾,被gc回收。

查找操作:value ,bool = map[key];value为返回的value,bool为是否返回,要么true要么false。

func main() {a := make(map[int]string)// 增加操作a[2020] = "张三"a[2019] = "李四"// 查找操作value, flag := a[2019]if flag {fmt.Println(value) // 李四} else {fmt.Println("查找不到")}fmt.Println(a) // map[2020:张三]
}

当然map还有一些其他的操作,这里进行一个简单的演示:

package main
import "fmt"
func main() {a := make(map[int]string)a[2020] = "张三"a[2019] = "李四"a[2018] = "王五"// 获取长度fmt.Println(len(a))// 遍历for k, v := range a {fmt.Printf("key为:%v value为 %v \n", k, v)}// 上操作b := make(map[string]map[int]string) // 嵌套map// 赋值b["班级1"] = make(map[int]string)b["班级1"][2020] = "张三"b["班级1"][2019] = "李四"b["班级1"][2018] = "王五"b["班级2"] = make(map[int]string)b["班级2"][2019] = "张三1"b["班级2"][2018] = "李四1"b["班级2"][2017] = "王五1"// 遍历for k, v := range b {fmt.Println(k)for k1, v1 := range v {fmt.Printf("key为:%v value为 %v \n", k1, v1)}}
}

最终呈现的效果如下:

相关文章:

【启程Golang之旅】掌握Go语言数组基础概念与实际应用

欢迎来到Golang的世界&#xff01;在当今快节奏的软件开发领域&#xff0c;选择一种高效、简洁的编程语言至关重要。而在这方面&#xff0c;Golang&#xff08;又称Go&#xff09;无疑是一个备受瞩目的选择。在本文中&#xff0c;带领您探索Golang的世界&#xff0c;一步步地了…...

COMSOL中液晶材料光学特性模拟

前面我们根据FDTD官方文档设置了液晶指向的模型。COMSOL也可以根据相似的方法设置各项异性的周期性变化的材料。 该方法参考了luneburg_lens的COMSOL文档 在给出的文件中&#xff0c;可以发现定义-变量中可以使用默认坐标作为变量&#xff0c;即xyz。因此&#xff0c;折射率也可…...

虚拟现实环境下的远程教育和智能评估系统(五)

查阅相关VR眼动注意力联合教育学相关论文 1.Exploring Eye Gaze Visualization Techniques for Identifying Distracted Students in Educational VR&#xff08;IEEE VR 2020&#xff09; 摘要&#xff1a;我们提出了一种架构&#xff0c;使VR教学代理能够响应眼动追踪监控…...

【算法】模拟算法——Z字形变换(medium)

题解&#xff1a;模拟算法——Z字形变换(medium) 目录 1.题目2.题解3.参考代码4.总结 1.题目 题目链接&#xff1a;LINK 2.题解 利用模拟&#xff0c;来解决问题。 首先创建出一个O(numRows*n)的数组来&#xff0c;并按照题目要求把每个字符按顺序填进去。 这里以numRows…...

上位机图像处理和嵌入式模块部署(f103 mcu获取唯一id)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 对于stm32f103系列mcu来说&#xff0c;一般每一颗原厂的mcu&#xff0c;都会对应一个唯一的id。那这个id可以用来做什么用呢&#xff1f;个人认为&…...

运筹学_3.运输问题(特殊的线性规划)

目录 前言3.1 平衡运输问题中初始基可行解确定运输问题平衡运输与非平衡运输平衡运输问题的数学模型单纯形法解决平衡运输问题&#xff0c;初始可行基的确认 3.2 平衡运输问题的最优解判别求检验数表上作业法 3.3 产销不平衡的运输问题运输问题中产大于销的问题运输问题中产小于…...

科研项目书写作学习(持续更新中...)

写好一个科研项目书也是科研中很重要的一部分&#xff0c;所以借这篇博客做一个积累。还是以模块化的方式吧&#xff0c;后面慢慢那再整合逻辑。可能写的也不是很好&#xff0c;慢慢提升吧~ 背景 科研项目书的背景怎么写&#xff1f;首先要突出问题的价值(也就是做此研究的动…...

男士内裤哪个品牌好一点?2024热门男士内裤推荐

男人的内裤保质期只取决于被别人看见的次数&#xff0c;如果某条内裤从未被别人看见过&#xff0c;那它永远都是你的新内裤。也就是说&#xff0c;只要穿着破内裤这尴尬的瞬间没被目击&#xff0c;男人就能永远和一条内裤在一起。 实际上如果长时间不更换男士内裤&#xff0c;…...

Llama模型家族之RLAIF 基于 AI 反馈的强化学习(六) RLAIF 代码实战

LlaMA 3 系列博客 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;一&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;二&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;三&#xff09; 基于 LlaMA…...

计算机tcp/ip网络通信过程

目录 &#xff08;1&#xff09;同一网段两台计算机通信过程 &#xff08;2&#xff09;不同网段的两台计算机通信过程 &#xff08;3&#xff09;目的主机收到数据包后的解包过程 &#xff08;1&#xff09;同一网段两台计算机通信过程 如果两台计算机在同一个局域网中的同…...

42.开发中对String.format()的使用之空位补齐

用于空位补齐 Int x1; //对于传入的数字做处理&#xff0c;如果传入的数字不足三位&#xff0c;则使用数字0自动补齐 String numString.format(“%”3”d”,x); System.out.println(“num”num);//输出结果为&#xff1a;001 也可以简写成&#xff1a; String num2String…...

通用代码生成器应用场景四,跨编程语言翻译

通用代码生成器应用场景四&#xff0c;跨编程语言翻译 如果您有一个Java工程&#xff0c;想把它移植到Rust或Golang语言中去&#xff0c;希望尽可能加快研发速度。 如果您的系统是通用代码生成器开发的&#xff0c;保留了系统的SGS源文件或者SGS2的Excel模板&#xff0c;您可…...

β-烟酰胺单核苷酸(NMN)功能不断得到验证 市场规模呈增长态势

β-烟酰胺单核苷酸&#xff08;NMN&#xff09;功能不断得到验证 市场规模呈增长态势 β-烟酰胺单核苷酸&#xff08;β-Nicotinamide mononucleotide&#xff0c;NMN&#xff09;是一种生物活性分子&#xff0c;是一种辅酶Ⅰ&#xff08;NAD&#xff09;的前体&#xff0c;也是…...

深入理解 Go 语言中的字符串不可变性与底层实现

文章目录 前言1 字符串类型的数据结构组成2 为什么要这么设计数据结构&#xff1f;3 为什么说字符串类型不可修改&#xff1f;4 如何实现字符串的修改&#xff1f;5 为什么字符串修改的字面量用单引号&#xff1f;6 如何判断字符串的修改新建了一个字符串&#xff1f;7 字符串的…...

采购订单审批和取消例子

文章目录 1 Introduction2 Example 1 Introduction This is a exmaple for releaseing po and reseting po. 2 Example DATA:lw_in TYPE zmms015,lw_out TYPE zmms015_out,lt_head LIKE TABLE OF ZMMT003_head,lw_head TYPE ZMMT003_head,lt_item TYPE zmmt003_item_t,lt…...

PHP:集成Xunsearch生成前端搜索骨架

如果是安装宝塔&#xff0c;我们在集成xunsearch的时候就会比较简单&#xff0c;后面我们在介绍其他的接入方式&#xff1b; 首先我们进入到宝塔管理后台&#xff1a;【软件商店】-【输入xun】-【点击xunsearch】直接安装即可 安装成功之后&#xff0c;会自动在www/server中创…...

ThreadLocal详解,与 HashMap 对比

ThreadLocal原理&#xff0c;使用注意事项&#xff0c;解决哈希冲突方式->和HashMap对比 ThreadLocal 原理&#xff1a; ThreadLocal 是 Java 中的一个线程级别的变量&#xff0c;它允许您在不同线程之间存储和访问相同变量的不同副本&#xff0c;每个线程都拥有自己的副本&…...

flask流式接口

一、接口封装 from flask import Flask, request, Response, stream_with_context app Flask(__name__) app.logger.disabled Truedef chat_stream_(prompt):for new_text in [1,2,3]:yield new_textapp.route(/chat_stream, methods[POST]) def chat_stream():prompt requ…...

MatLab命令行常用命令记录

文章目录 MatLab常用命令行MatLab常用按键标点说明 MatLab常用命令行 Matlab常用命令用来管理目录、命令、函数、变量、工作区、文件及窗口。常用命令如下表 命令作用cd显示或改变当前文件夹load加载指定文件的变量dir显示当前文件夹或指定目录下的文件diary日志文件命令type…...

Linux —— MySQL操作(1)

一、用户与权限管理 1.1 创建与赋予权限 create user peter% identified by 123465 # 创建用户 peter&#xff0c;# %&#xff1a;允许所有用户登录这个用户访问数据库 刚创建的新用户是什么权限都没有&#xff0c;需要赋予权限 grant select on mysql.* to peter%; # 赋予…...

TCP四次握手与http协议版本区别

TCP四次挥手(图解)-为何要四次挥手 当客户端和服务器通过三次握手建立了TCP连接以后&#xff0c;当数据传送完毕&#xff0c;肯定是要断开TCP连接的啊。那 对于TCP的断开连接&#xff0c;这里就有了神秘的“四次挥手”。 第一次挥手&#xff1a;主机1&#xff08;可以使客户端…...

【机器学习】洞悉数据奥秘:决策树算法在机器学习中的魅力

在机器学习的分类和回归问题中&#xff0c;决策树是一种广泛使用的算法。决策树模型因其直观性、易于理解和实现&#xff0c;以及处理分类和数值特征的能力而备受欢迎。本文将解释决策树算法的概念、原理、应用、优化方法以及未来的发展方向。 &#x1f680;时空传送门 &#x…...

redis(17):什么是布隆过滤器?如何实现布隆过滤器?

1 布隆过滤器介绍 布隆过滤器(Bloom Filter)是一种空间效率极高的概率型数据结构,用于判断一个元素是否在一个集合中。它基于位数组和多个哈希函数的原理,可以高效地进行元素的查询,而且占用的空间相对较小,如下图所示: 根据 key 值计算出它的存储位置,然后将此位置标…...

STM32自己从零开始实操03:输出部分原理图

一、继电器电路 1.1指路 延续使用 JZC-33F-012-ZS3 继电器&#xff0c;设计出以小电流撬动大电流的继电器电路。 &#xff08;提示&#xff09;电路需要包含&#xff1a;三极管开关电路、续流二极管、滤波电容、指示灯、输出部分。 1.2数据手册重要信息提炼 联系排列&…...

Unity中将图片做成Prefab的步骤

Unity中将图片做成Prefab的步骤 在Unity中&#xff0c;将一张图片做成Prefab是一个常见的操作。Prefab是Unity中的一种资源类型&#xff0c;可以让你预先定义一个游戏对象&#xff0c;然后在场景中多次实例化它。以下是详细的步骤&#xff1a; 步骤一&#xff1a;准备图片资源…...

Web前端三大主流框架:React、Vue和Angular

在当前的Web开发领域&#xff0c;前端框架的选择对于项目的成功至关重要。作为一名资深的IT技术员&#xff0c;我对前端技术的发展和行业趋势保持着持续的关注。本文将介绍当前Web前端三大主流框架&#xff1a;React、Vue和Angular&#xff0c;并分析它们各自的优势。 React&a…...

安全风险 - 检测设备是否为模拟器

在很多安全机构的检测中&#xff0c;关于模拟器的运行环境一般也会做监听处理&#xff0c;有的可能允许执行但是会提示用户&#xff0c;有的可能直接禁止在模拟器上运行我方APP 如何判断当前 app 是运行在Android真机&#xff0c;还是运行在模拟器? 可能做 Framework 的朋友思…...

maven的下载以及配置的详细教程(附网盘下载地址)

文章目录 下载配置IDEA内部使用配置 下载 1.百度网盘下载 链接: https://pan.baidu.com/s/1LD9wOMFalLL49XUscU4qnQ?pwd1234 提取码: 1234 2.解压即可 配置 1.打开安装文件下conf下的settings.xml文件&#xff0c;我的如下 2.修改配置信息&#xff08;目的是为了修改本地…...

Unity3D 主城角色动画控制与消息触发详解

前言 在游戏开发中&#xff0c;角色动画控制和消息触发是非常重要的一部分&#xff0c;它可以让游戏更加生动和互动。本文将详细介绍如何在Unity3D中实现主城角色动画控制与消息触发。 对惹&#xff0c;这里有一个游戏开发交流小组&#xff0c;大家可以点击进来一起交流一下开…...

【Endnote】如何在word界面加载Endnote

如何在word界面加载Endnote 方法1&#xff1a;方法2&#xff1a;从word入手方法3&#xff1a;从CWYW入手参考 已下载EndNote,但Word中没有显示EndNote&#xff0c;应如何加载显示呢&#xff1f; 方法1&#xff1a; 使用EndNote的Configure EndNote.exe 。 具体步骤为&#x…...