01_01_Go语言基础知识

news2024/10/6 10:29:53

01_01_Go语言基础知识

    • 定义变量
    • 内建变量类型
    • 强制类型转换
    • 常量与枚举
    • 要点总结
    • 条件语句
      • if 举例
      • switch 举例
    • for 循环
    • 函数
    • 指针
    • 数组

定义变量

使用 var 关键字

使用 var 关键字, 可以放在函数内, 或直接放在包内均可

// 定义 a, b, c 三个变量 类型都是 bool  变量可以不赋初始值
var a, b, c bool  

// 定义 s1, s2 两个变量 类型都是 string  定义变量的同时赋初始值
var s1, s2 string = "hello", "world"  

// 使用 var 集中定义变量
var (
	age = 18
	name = "baoxing"
	isMan = true
)

// 让编译器自动决定类型, 并且使用 := 定义变量  注意 := 只能在函数内使用
a, b, c, s := 3, 4, true, "def"

内建变量类型

  • boolstring

  • (u)int, (u)int8, (u)int16, (u)int32, (u)int64, uintptr

  • byte, rune

  • float32, float64, complex64, complex128

强制类型转换

类型转换是强制的

var a, b int = 3, 4
// 错误 编译不通过 因 Sqrt 参数类型 为 float64 返回类型 为 float64
var c = math.Sqrt(a * a + b * b)
// 正确 强制转换类型后 
var c = int(math.Sqrt(float64(a*a + b*b)))

常量与枚举

  1. 使用 const 关键字, 可以指定类型 也可以不指定类型(不指定时可以作为各种类型使用,如下面的 4 中示例 )
const a, b = 3, 4
const a, b int = 3, 4
  1. 可以定义在函数内, 也可以定义在包内
// 1) 定义在函数内
func consts() {
	const filename = "abc.txt"
	fmt.Println(filename)
}
// 2) 定义在包内
const filename = "abc.txt"
func consts() {
	fmt.Println(filename)
}
  1. 可以一组常量集中定义
func consts() {
	const (
		filename = "abc.txt"
		a, b     = 3, 4
	)
	fmt.Println(filename, a, b)
}
  1. 定义常量时不指定类型, 此时因为math.Sqrt() 需要的参数为 float64 此时 常量类型就是 float64
func consts() {
	const a, b = 3, 4
	var c = int(math.Sqrt(a*a + b*b))
	fmt.Println( c)
}
  1. 枚举类型(特殊的常量)
    1. 普通枚举类型
    2. 自增枚举类型
// 常规用法
func enums() {
	const (
		cpp    = 0
		java   = 1
		python = 2
		golang = 3
	)
	fmt.Println(cpp, java, python, golang)
    // 打印输出 0 1 2 3
}
// ==========================================================================
// 简化写法 自增值枚举类型
func enums() {
	const (
		cpp = iota
		java
		python
		golang
	)
	fmt.Println(cpp, java, python, golang)
	// 打印输出 0 1 2 3
}
// ==========================================================================
// 跳过 中间的  1
func enums() {
	const (
		cpp = iota
		_
		python
		golang
		javascript
	)
	fmt.Println(cpp, python, golang, javascript)
	// 打印输出 0 2 3 4
}
// ==========================================================================
// 高级用法
func enums() {
	const (
		b = 1 << (10 * iota)
		kb
		mb
		gb
		tb
		pb
	)
	fmt.Println(b, kb, mb, gb, tb, pb)
	// 打印输出 1 1024 1048576 1073741824 1099511627776 1125899906842624
}

要点总结

  • 变量类型写在变量名之后
  • 编译器可以推测变量类型
  • 没有 char 只有 rune
  • 原生支持复数类型

条件语句

  • if 的条件里不需要括号
  • if 的条件里可以赋值
  • switch 会自动 break , 除非使用 fallthrough
  • switch 后面可以没有表达式, 可以直接 switch 多个条件

if 举例

// 常规写法
func main() {
	const filename = "abc.txt"
	contents, err := ioutil.ReadFile(filename)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Printf("%s \n", contents)
	}
}
// ==========================================================================
// 特有写法 先执行前面的赋值  再判断 注意此时的 contents 仅在 if 或 else 内部可以访问到
func main() {
	const filename = "abc.txt"
	if contents, err := ioutil.ReadFile(filename); err != nil {
		fmt.Println(err)
	} else {
		fmt.Printf("%s \n", contents)
	}
}

switch 举例

func eval(a, b int, op string) int {
	var result int
	switch op {
	case "+":
		result = a + b
	case
		"-":
		result = a - b
	case
		"*":
		result = a * b
	case "/":
		result = a / b
	default:
		panic("unsupported operator:" + op)
	}
	return result
}
func main() {
	fmt.Println(eval(1, 2, "+"))
	// 输出打印 3
}
// ==========================================================================
// switch 后面没有表达式写法
func grade(score int) string {
	g := ""
	switch {
	case score < 0 || score > 100:
		panic(fmt.Sprintf("Wrong score: %d", score))
	case score < 60:
		g = "F"
	case score < 80:
		g = "C"
	case score < 90:
		g = "B"
	case score < 100:
		g = "A"
	}
	return g
}
func main() {
	fmt.Println(
		grade(0),
		grade(59),
		grade(60),
		grade(82),
		grade(99),
		grade(100),
		//grade(101),
	)
	// 输出打印 F F C B A
}

for 循环

  • for 的条件里不需要括号
  • for 的条件里可以省略初始条件, 结束条件, 递增表达式
  • 没有 while
// 基本使用
func basic() int {
	sum := 0
	for i := 0; i <= 100; i++ {
		sum += i
	}
	return sum
}

func main() {
	fmt.Println(basic())
}
// ==========================================================================
// 省略初始条件
func convertToBin(n int) string {
	result := ""
	for ; n > 0; n /= 2 {
		lsb := n % 2
		result = strconv.Itoa(lsb) + result
	}
	return result
}

func main() {
	fmt.Println(
		convertToBin(5), // 打印 101
		convertToBin(13),  // 打印 1101
	)
}
// ==========================================================================
// 只有结束条件
func printFile(filename string) {
	file, err := os.Open(filename)
	if err != nil {
		panic(err)
	}
	scanner := bufio.NewScanner(file)
	// 只有结束条件
	for scanner.Scan() {
		// 一次读取一行
		fmt.Println(scanner.Text())
	}
}
func main() {
	printFile("abc.txt")
}
// ==========================================================================
// 省略 初始条件, 结束条件, 递增表达式 (无限循环)
func forever() {
	for {
		fmt.Println("abc")
	}
}
func main() {
	forever()
}

函数

  • 返回值类型写在最后面
  • 可以返回多个值
  • 函数可以作为参数
  • 函数返回多个值时可以起名字(仅用于非常简单的函数, 对于调用者而言没有区别)
  • 可变参数列表
  • 没有默认参数, 可选参数
// 基本使用
func eval(a, b int, op string) int {
	switch op {
	case "+":
		return a + b
	case "-":
		return a - b
	case "*":
		return a * b
	case "/":
		return a / b
	default:
		panic("unsupported operation: " + op)
	}
}
func main() {
	fmt.Println(eval(3, 4, "*"))  // 打印输出 12
}
// ==========================================================================
// 多个返回值
// 13 / 3 = 4 ... 1
func div(a, b int) (int, int) {
	return a / b, a % b
}
func main() {
	fmt.Println(div(13, 3))  // 打印输出 4 1
}
// ==========================================================================
// 多个返回值带名称
// 13 / 3 = 4 ... 1 q 代表商 r 代表余数
func div(a, b int) (q, r int) {
	//q = a / b
	//r = a % b
	//return
	return a / b, a % b
}
func main() {
	q, r := div(13, 3)
	fmt.Println(q, r)  // 打印输出 4 1
}
// ==========================================================================
// 多个返回值  匿名变量的使用 _
// q 代表商 r 代表余数
func div(a, b int) (q, r int) {
	return a / b, a % b
}
func eval(a, b int, op string) int {
	switch op {
	case "+":
		return a + b
	case "-":
		return a - b
	case "*":
		return a * b
	case "/":
		q, _ := div(a, b)
		return q
	default:
		panic("unsupported operation: " + op)
	}
}
func main() {
	fmt.Println(eval(28, 4, "/"))  // 打印输出 7
}

// ==========================================================================
// 多个返回值  Go 语言常用方式
func eval(a, b int, op string) (res int, error error) {
	switch op {
	case "+":
		return a + b, nil
	case "-":
		return a - b, nil
	case "*":
		return a * b, nil
	case "/":
		return a / b, nil
	default:
		return 0, fmt.Errorf("unsupported operation: %s", op)
	}
}
func main() {
	fmt.Println(eval(28, 4, "**")) // 打印输出:  0 unsupported operation: **

	if result, err := eval(3, 4, "**"); err != nil {
		fmt.Println("Error:", err)  //  打印输出:  Error: unsupported operation: **
	} else {
		fmt.Println(result)
	}
}

// ==========================================================================
// 函数式编程思想 重写 eval 函数  注意: 形参为函数
// 写法 1 单独定义个函数 pow 传递给 apply 函数使用
// apply 函数有三个参数 分别为 op, a , b
func apply(op func(int, int) int, a, b int) int {
	pointer := reflect.ValueOf(op).Pointer()
	opName := runtime.FuncForPC(pointer).Name()
	fmt.Printf("Calling function %s with args (%d. %d) \n", opName, a, b)
	// 将 a, b 参数传递给 op 函数使用
	return op(a, b)
}
func pow(a, b int) int {
	return int(math.Pow(float64(a), float64(b)))
}
func main() {
	res := apply(pow, 3, 4)
	fmt.Println(res)  // 打印输出
}

// 写法 2 给 apply 函数传递一个匿名函数
// apply 函数有三个参数 分别为 op, a , b
func apply(op func(int, int) int, a, b int) int {
	pointer := reflect.ValueOf(op).Pointer()
	opName := runtime.FuncForPC(pointer).Name()
	fmt.Printf("Calling function %s with args (%d. %d) \n", opName, a, b)
	// 将 a, b 参数传递给 op 函数使用
	return op(a, b)
}
func main() {
	// 匿名函数写法
    res := apply(
        func(a int, b int) int {
            return int(math.Pow(float64(a), float64(b)))
        }, 3, 4)
	fmt.Println(res) // 打印输出
}
// ==========================================================================
// 可变参数列表 

func sum(numbers ...int) int {
	s := 0
	for i := range numbers {
		s += numbers[i]
	}
	return s
}
func main() {
	fmt.Println(sum(1, 2, 3))  // 打印输出 6
}

指针

  • go 语言的指针不能运算
func main() {
   // a 是 int 等于 2
   var a int = 2
   // pa 是 a 的指针, &a 表示 a 的地址  go 语言 *int 代表的是指针
   var pa *int = &a
   *pa = 3
   fmt.Println(a) // 打印输出 3
}

参数传递

Go 语言只有 传递一种方式

  • 值传递(做了一份拷贝,拷贝完之后和原来的没有关系,不会改变原来的值)
  • 引用传递(不拷贝) — 在 Go语言中不存在

以下为 C++ 中的一段代码

image-20221212234359188

Go 语言是使用指针和值传递来配合使用, 来解决拷贝效率问题

image-20221212234826060

image-20221212235259383

image-20221212235710342

// 例1
func swap(a, b int) {
   b, a = a, b
}
func main() {
   a, b := 3, 4
   swap(a, b)
   fmt.Println(a, b) // 打印输出 3 4   因为 a, b 是值传递  传过去的只是拷贝的值
}

// 例2
func swap(a, b *int) {
	*b, *a = *a, *b
}
func main() {
	a, b := 3, 4
	swap(&a, &b)
	fmt.Println(a, b) // 打印输出 4  3   因为交换的是地址,  a 所指向的内容给 b, b 所指向的内容给 a
}

// 例3
func swap(a, b int) (int, int) {
	// 把交换的结果返回回去
	return b, a
}
func main() {
	a, b := 3, 4
	// 用 a, b 去接收返回结果
	a, b = swap(a, b)
	fmt.Println(a, b) // 打印输出 4  3   这种 swap 定义方法才是更好的 相对于 例2
}

数组

  • 数量写在类型前
  • 可通过 _ 来省略变量
  • 不仅 range, 任何地方都可以通过 _ 省略变量
  • 如果只要 i 下标 , 可以写成 for i := range numbers
// 例1
func main() {
	// 定义数组 先定义长度再定义类型
	var arr1 [5]int
	// 使用 := 定义数组
	arr2 := [3]int{1, 3, 5}
	// 让编辑器计算长度
	arr3 := [...]int{2, 4, 6, 8}
	// 定义一个二维数组 4行5列  从前往后读
	var grade [4][5]int

	fmt.Println(arr1, arr2, arr3)
	// 打印输出
	// [0 0 0 0 0] [1 3 5] [2 4 6 8]
	fmt.Println(grade)
	// 打印输出
	// [[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]
}

// 例2
// 遍历数组 第一种方式
func main() {
	arr3 := [...]int{2, 4, 6, 8}
	// 遍历数组
	for i := 0; i < len(arr3); i++ {
		fmt.Println(arr3[i])
	}
}
// 输出
//2
//4
//6
//8

// 遍历数组 第二种方式
func main() {
	arr3 := [...]int{2, 4, 6, 8}
	// 遍历数组
	for i := range arr3 {
		fmt.Println(arr3[i])
	}
}
// 输出
//2
//4
//6
//8

// 遍历数组 获取下标同时获取值
func main() {
	arr3 := [...]int{2, 4, 6, 8}
	// 遍历数组
	for i, v := range arr3 {
		fmt.Println(i, v)
	}
}
// 输出
//0 2
//1 4
//2 6
//3 8

// 遍历数组 只想获取值不想获取下标
func main() {
	arr3 := [...]int{2, 4, 6, 8}
	// 遍历数组
	for _, v := range arr3 {
		fmt.Println(v)
	}
}
// 输出
//2
//4
//6
//8

为什么要用 range

  • 意向明确, 美观
  • C++ 没有类似能力 有其他第三方的库
  • Java/Python 只能 for each value, 不能同时获取 i, v
  • [3]int 和 [5]int 是不同类型
  • 调用 func f(arr [10]int)拷贝数组
  • go 语言中一般不直接使用数组

数组是值类型

// 例1
func printArr(arr [5]int) {
	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}

	printArr(arr1)
	//printArr(arr2) // 编译出错 [3]int 和 [5]int 是两种类型
	fmt.Println("==================")
	printArr(arr3)
}
// 打印输出
//0 0
//1 0
//2 0
//3 0
//4 0
//==================
//0 2
//1 4
//2 6
//3 8
//4 10

// 例2 可以说明数组是值类型
func printArr(arr [5]int) {
	for i, v := range arr {
		fmt.Println(i, v)
	}
	arr[0] = 100
}
func main() {
	var arr1 [5]int
	arr3 := [...]int{2, 4, 6, 8, 10}

	printArr(arr1)
	fmt.Println("==================")
	printArr(arr3)
	fmt.Println(arr1, arr3)
}
// 打印输出
//0 0
//1 0
//2 0
//3 0
//4 0
//==================
//0 2
//1 4
//2 6
//3 8
//4 10
//[0 0 0 0 0] [2 4 6 8 10]

// 例3 可以说明数组是值类型
func printArr(arr [5]int) {
	arr[0] = 100
	for i, v := range arr {
		fmt.Println(i, v)
	}
}
func main() {
	var arr1 [5]int
	arr3 := [...]int{2, 4, 6, 8, 10}

	printArr(arr1)
	fmt.Println("==================")
	printArr(arr3)
	fmt.Println(arr1, arr3)
}
// 打印输出
//0 100
//1 0
//2 0
//3 0
//4 0
//==================      
//0 100
//1 4
//2 6
//3 8
//4 10
//[0 0 0 0 0] [2 4 6 8 10]

// 例4 使用指针传递,就可以改变数组的值了
func printArr(arr *[5]int) {
	arr[0] = 100
	for i, v := range arr {
		fmt.Println(i, v)
	}
}
func main() {
	arr3 := [...]int{2, 4, 6, 8, 10}
	printArr(&arr3)
	fmt.Println(arr3)
}
// 打印输出
//0 100
//1 4
//2 6
//3 8
//4 10
//[100 4 6 8 10]

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

别搞错了,nonTransitiveRClass 不能解决资源冲突!

前言 nonTransitiveRClass&#xff1a;非传递性 R 类的属性&#xff0c;在 gradle.properties 文件里使用。 不少开发者可能听过它&#xff0c;但了解可能仅限于是对 R 文件做了优化&#xff0c;甚至以为它可以解决资源冲突&#xff01;但它到底做了什么优化、能否解决资源冲突…

【序列召回推荐】(task2)序列召回GRU4Rec模型

学习总结&#xff1a; 一般的RNN模型我们的输入和输出是什么&#xff0c;我们对RNN输入一个序列 X[x1,x2,...,xn]X [x^1,x^2,...,x^n]X[x1,x2,...,xn] &#xff0c;注意我们序列中的每一个节点都是一个向量&#xff0c;那么我们的RNN会给我们的输出也是一个序列 Y[y1,y2,...,…

【python黑帽子】——(一)搭建扫描器入门介绍

作者名&#xff1a;Demo不是emo 主页面链接&#xff1a;主页传送门创作初心&#xff1a;舞台再大&#xff0c;你不上台&#xff0c;永远是观众&#xff0c;没人会关心你努不努力&#xff0c;摔的痛不痛&#xff0c;他们只会看你最后站在什么位置&#xff0c;然后羡慕或鄙夷座右…

Python安装教程

Python安装 1.浏览器打开网址:www.python.org 2.根据电脑系统选择下载 3.确定电脑系统属性&#xff0c;此处我们以win10的64位操作系统为例 4.安装python 3.6.3 双击下载的安装包 python-3.6.3.exe 注意要勾选&#xff1a;Add Python 3.6 to PATH 点击 Customize installat…

4 种经典方法IB 数学证明题分享给大家

学习数学时感觉最有意思的题目就是证明题了&#xff0c;证明题能练习一种能力&#xff1a; 你知道一件事情时对的&#xff0c;怎么说清楚它是对的&#xff1b;你认为一件事情时错的&#xff0c;怎么说清楚它是错的。 这和生活中的辩论有点像&#xff0c;要有理有据地说清楚原因…

[附源码]Node.js计算机毕业设计蛋糕店会员系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

Servlet的生命周期

servlet 1.servlet是什么 2.servlet生命周期 3. servlet 工作原理 4 .ServletContextListener 什么是Servlet&#xff1f; Servlet是JavaWeb的 三大组件之一 &#xff0c;它属于动态资源。Servlet的作用是处理请求&#xff0c;服务器会把接收到的请求交给Servlet来处理&…

基于RSS和TOA两种方法的无线传感器网络定位测量算法matlab仿真

up目录 一、理论基础 二、核心程序 三、测试结果 一、理论基础 无线传感器网络(Wireless Sensor Networks, WSN)是一种分布式传感网络&#xff0c;它的末梢是可以感知和检查外部世界的传感器。WSN中的传感器通过无线方式通信&#xff0c;因此网络设置灵活&#xff0c;设备位…

去哪儿旅行微服务架构实践,全文带图加详细解析,带你多方面了解

文章目录一、背景介绍二、微服务架构模式的最佳实践三、微服务开发效率提升实践四、服务治理实践五、ServiceMesh 尝试六、总结今天我带来的主题是去哪儿旅行 微服务架构实践。我将从以下几个方面进行介绍&#xff1a;背景介绍微服务架构模式的最佳实践微服务开发效率的提升实践…

前台用户注册_发送邮件配置

在用户注册成功后&#xff0c;要向用户的邮箱发送一封激活邮件&#xff0c;发送邮件需要在系统中配置发件人&#xff0c;同学们使用自己的邮箱作为发件人即可。 配置邮箱第三方登录。 我们在系统中使用邮箱发送邮件属于第三方登录&#xff0c;而市面上的邮箱默认是不能第三方…

自监督学习系列(四):基于蒸馏的图片掩码学习

前文 好久不见&#xff01;自监督系列文章继续更新啦&#xff01;在前几期的文章我们介绍了基于辅助任务&#xff0c;对比学习&#xff0c;和图片掩码学习的自监督学习范式 (对比学习&#xff0c;图片掩码学习其实也可以归属于基于辅助任务的自监督学习&#xff0c;由于这两类…

百度安全怎么查询,怎么彻底解决百度安全弹出的风险提示

当我们在百度搜索自己的网站时&#xff0c;搜索结果中出现各种风险提示&#xff0c;比如安全联盟提醒您&#xff1a;该网站可能存在安全风险&#xff0c;请谨慎访问&#xff01; 别慌&#xff01;今天我们就来解决百度安全弹出的风险提示的问题。 第一步&#xff1a;查询网站…

Python 自动化测试框架unittest与pytest的区别

这篇文章主要讲unittest与pytest的区别&#xff0c;pytest相对unittest而言&#xff0c;代码简洁&#xff0c;使用便捷灵活&#xff0c;并且插件很丰富。 Unittest vs Pytest 主要从用例编写规则、用例的前置和后置、参数化、断言、用例执行、失败重运行和报告这几个方面比较…

传奇GOM引擎微端架设教程

传奇GOM引擎微端架设教程 GOM引擎架设微端需要准备好微端程序&#xff0c;用网站下载在服务器的版本 &#xff08;注&#xff1a;本文章图有打码处因平台GZ原因需打码望读者理解&#xff09; Mirserver文件一般都是自带微端程序的&#xff0c;偶尔也有版本没有微端程序那我们…

基于多目标遗传算法(NSGA-II)和多目标粒子群算法(MOPSO)的分布式仿真系统双目标负载平衡模型【Matlab代码实现】

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清…

Oracle单机部署:GI安装

Oracle单机部署&#xff1a;GI安装存储配置ASM磁盘空间评估GI单机安装配置GI图形化安装流程安装后测试&#x1f42c; 使用grid用户来安装GI。 存储配置 Oracle存储支持Oracle ASM、Oracle ACFS、本地文件系统、网络文件系统&#xff08;NFS/NAS&#xff09;、Oracle Memory S…

RK3588平台开发系列讲解(RTC篇)RTC的使用

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、RTC简介二、HYM8563驱动配置2.1、设备树配置2.1、驱动代码三、RTC的使用3.1、SYSFS接口3.2、PROCFS接口3.3、IOCTL接口沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍RK3588平台RTC驱动及使用方…

玩以太坊链上项目的必备技能(基本类型转换以及推断-Solidity之旅六)

基本类型之间的转换 熟悉过其他编程语言的您&#xff0c;对基本类型之间的转换并不陌生吧&#xff01;当然&#xff0c;这基本类型进行转换可分为隐式转换和显示转换。 隐式转换 Solidity 支持隐式转换&#xff0c;通过编译器自动进行转换&#xff0c;而不要开发人员的干涉&…

信道估计算法误码率仿真,对比不同导频长度,对比不同信道估计算法包括CS-OMP,LS,MMSE

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 所谓信道估计&#xff0c;就是从接收数据中将假定的某个信道模型的模型参数出来的过程。如果信道是线性的话&#xff0c;那么信道估计就是对系统冲激响应进行估计。 CS-OMP 正则正交匹配追踪(Re…

分布式操作系统 - 5.分布式命名管理

文章目录1.基本概念2.非结构化命名管理2.1 简单的实体定位方法&#xff1a;广播和多播方法&#xff08;1&#xff09;广播方法&#xff08;broadcast&#xff09;&#xff08;2&#xff09;多播方法&#xff08;multicast&#xff09;&#xff08;3&#xff09;问题&#xff1a…