深入分析Go语言与C#的异同

news2024/11/24 19:36:44

摘要:本文由葡萄城技术团队于CSDN原创并首发。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。

前言

为了更加深入地介绍Go语言以及与C#语言的比较,本文将会从多个维度出发进行详细的阐述。首先,将从Go语言的关键字方面介绍Go与C#在语言特性上的异同,并且探讨两种语言在关键字方面的优化和不足之处。其次,本文将通过代码示例、性能测试等方式,展示Go语言在关键字方面的优势,从而为读者呈现出Go语言的强大之处。除此之外,为了更好地帮助读者理解Go语言,本文还将介绍一些优秀的Go语言工具和社区资源,供读者进一步学习和探索。相信通过这些内容的全面介绍,读者们会对Go语言有更全面深入的认识和了解。

文章目录:

1.Go的前世今生

​ 1.1Go语言诞生的过程

​ 1.2逐步成型

​ 1.3正式发布

​ 1.4 Go安装指导

2.Go和C#的关键字比较

​ 2.1Go与C#都有的关键字

​  2.1.1.Var

​  2.1.2. Switch-case-default

​  2.1.3.If-else

​  2.1.4. For

​  2.1.5. Struct

​​ 2.2Go与C#不太一样但是意思差不多的关键字

​  2.2.1. Package与namespace

​​  2.2.2. Import与using

​​  2.2.3. Type与class

​  2.2.4. Defer与finally

​ 2.3Go有而 C#没有的关键字

​​  2.3.1. Fallthrough

​​  2.3.2.Func

3.文章小结

4.扩展链接

1.Go的前世今生

1.1Go语言诞生的过程

话说早在 2007 年 9 月的一天,Google 工程师 Rob Pike 和往常一样启动了一个 C++项目的构建,按照他之前的经验,这个构建应该需要持续 1 个小时左右。这时他就和 Google公司的另外两个同事 Ken Thompson 以及 Robert Griesemer 开始吐槽并且说出了自己想搞一个新语言的想法。当时 Google 内部主要使用 C++构建各种系统,但 C++复杂性巨大并且原生缺少对并发的支持,使得这三位大佬苦恼不已。

第一天的闲聊初有成效,他们迅速构想了一门新语言:能够给程序员带来快乐,能够匹配未来的硬件发展趋势以及满足 Google 内部的大规模网络服务。并且在第二天,他们又碰头开始认真构思这门新语言。第二天会后,Robert Griesemer 发出了如下的一封邮件:

可以从邮件中看到,他们对这个新语言的期望是:**在 C 语言的基础上,修改一些错误,删除一些诟病的特性,增加一些缺失的功能。**比如修复 Switch 语句,加入 import 语句,增加垃圾回收,支持接口等。而这封邮件,也成了 Go 的第一版设计初稿。

在这之后的几天,Rob Pike 在一次开车回家的路上,为这门新语言想好了名字Go。在他心中,”Go”这个单词短小,容易输入并且可以很轻易地在其后组合其他字母,比如 Go 的工具链:goc 编译器、goa 汇编器、gol 连接器等,并且这个单词也正好符合他们对这门语言的设计初衷:简单。

1.2逐步成型

在统一了 Go 的设计思路之后,Go 语言就正式开启了语言的设计迭代和实现。2008 年,C语言之父,大佬肯·汤普森实现了第一版的 Go 编译器,这个版本的 Go 编译器还是使用C语言开发的,其主要的工作原理是将Go编译成C,之后再把C编译成二进制文件。到2008年中,Go的第一版设计就基本结束了。这时,同样在谷歌工作的伊恩·泰勒(Ian Lance Taylor)为Go语言实现了一个gcc的前端,这也是 Go 语言的第二个编译器。伊恩·泰勒的这一成果不仅仅是一种鼓励,也证明了 Go 这一新语言的可行性 。有了语言的第二个实现,对Go的语言规范和标准库的建立也是很重要的。随后,伊恩·泰勒以团队的第四位成员的身份正式加入 Go 语言开发团队,后面也成为了 Go 语言设计和实现的核心人物之一。罗斯·考克斯(Russ Cox)是Go核心开发团队的第五位成员,也是在2008年加入的。进入团队后,罗斯·考克斯利用函数类型是“一等公民”,而且它也可以拥有自己的方法这个特性巧妙设计出了 http 包的 HandlerFunc 类型。这样,我们通过显式转型就可以让一个普通函数成为满足 http.Handler 接口的类型了。不仅如此,罗斯·考克斯还在当时设计的基础上提出了一些更泛化的想法,比如 io.Reader 和 io.Writer 接口,这就奠定了 Go 语言的 I/O 结构模型。后来,罗斯·考克斯成为 Go 核心技术团队的负责人,推动 Go 语言的持续演化。到这里,Go 语言最初的核心团队形成,Go 语言迈上了稳定演化的道路。

1.3正式发布

2009年10月30日,罗伯·派克在Google Techtalk上做了一次有关 Go语言的演讲,这也是Go语言第一次公之于众。十天后,也就是 2009 年 11 月 10 日,谷歌官方宣布 Go 语言项目开源,之后这一天也被 Go 官方确定为 Go 语言的诞生日。

(Go语言吉祥物Gopher)

1.4.Go安装指导

1.Go语言安装包下载

Go 官网:https://golang.google.cn/

选择对应的安装版本即可(建议选择.msi文件)。

2.查看是否安装成功 + 环境是否配置成功

打开命令行:win + R 打开运行框,输入 cmd 命令,打开命令行窗口。

命令行输入 go version 查看安装版本,显示下方内容即为安装成功。


2.Go和C#的关键字比较

Go有25个关键字,而C#则有119个关键字(其中包含77个基础关键字和42个上下文关键字)。单从数量上来讲,C#的数量是Go的5倍之多,这也是Go比C#更简单的原因之一。

Go中的 25 个关键字:

breakdefaultfuncinterfaceselect
casedefergomapstruct
chanelsegotopackageswitch
constfallthroughifrangetype
continueforimportreturnvar

(Go关键字)

2.1Go与C#都有的关键字

  • break
  • case
  • const
  • continue
  • default
  • else
  • for
  • goto
  • if
  • interface
  • return
  • struct
  • switch
  • var

以上14个关键字是Go和C#共有的,它们之中大部分的用法都是完全相同的,这里重点说一下在Go中有特殊语法的关键字。

2.1.1.Var

Var在Go中用来表示定义变量,但语法和 C#不同。C#中只有一种定义变量的方法,而 Go中有两种,它们分别是:

  • 普通方式
var i int = 1

这种方式是Go的原始变量定义方式,一般包级别的变量都是这样定义的,并且如果定义那些编译器可以自动推断的类型,比如上述的例子,其后的类型可以省略。

  • 语法糖(是的,Go中也有语法糖…)
i, j := 1, "hello"

上述代码可简写为语法糖形式。事实上,Go代码中,90%变量都以此方式定义,因为几乎所有函数都有多个返回值,这种定义方式可省去许多麻烦。

2.1.2.Switch-case-default

Switch-case是一个连用的方法,但是case和default这两个关键字在 Go中除了可以和 switch 连用,还可以和select 语句连用。

同时Go中默认把 switch 语句的一个弊端修复了,即 switch 子句中不用再写 break 了。

switch n := "a"; n {

case n == "a":

fmt.Println("a")

case n == "b":

fmt.Println("b")

case n == "c":

fmt.Println("c")

}

上面这段代码的fmt是Go中的标准输出包,其中的Println函数等同于C#中的Console.WriteLine方法。同时这段代码的最终结果只会输出a,而 在C#中,同样的代码会把abc全部输出出来,这也是Go为何比C#简单的原因之一。

除此之外,switch 语句后面出现了一种全新的写法:n := “a”; n,这种写法在Go中的控制语句(if, else if, switch-case, for)中都可以使用,分号前是变量的定义,分号后是定义的判断条件。这种语法优点类似于 C#中的普通 for 循环的前两个子句。

最后,可以发现switch之后没有跟小括号,因为在Go中,控制块的子句后面都是不需要写小括号的,如果写了同样会被 gofmt 自动格式化掉。

2.1.3. If-else

Go中的if-else和C#几乎也是相同的,它俩最大的区别是Go中特殊语法,可以在 if-else 控制块中直接给变量赋值并且在控制块中使用这些值。

func isEven(n int) bool {

return n % 2 == 0

}

func main() {

if n := rand.Intn(1000); isEven(n) {

fmt.Printf("%d是偶数\\n", n)

} else {

fmt.Printf("%d是奇数\\n", n)

}

}

2.1.4. For

Go中的循环控制语句有且只有一个 for 关键字。而 C#中的 while、foreach 等在Go中都是通过 for 的各种变形达成的。

  • while 语句
for true {

// ...

}
  • for 语句
for i := 0; i < n; i++ {

// ...

}

Go中普通的 for 循环和 C#中唯一的差别就是 i++从表达式变成了语句。也就是说,Go中没有i = i++这样的语法,也没有++i这样的语法,只有i++这种语法。

  • foreach 语句
array := [5]int{1, 2, 3, 4, 5}

for index, value := range array {

// ...

}

foreach 语句的写法和 C#中很不相同,上述的例子是 foreach 遍历一个int类型的数组,其中用到了一个range关键字,这个关键字会把数组拆分成两个迭代子对象index 和value,for range可以遍历数组、切片、字符串、map 及通道(channel),这个语法同样类似于 JavaScript 的循环语法。例如下面的代码就是遍历数组中的值并输出:

for key, value := range []int{1, 2, 3, 4} {

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

}

代码输出如下:

key:0 value:1

key:1 value:2

key:2 value:3

key:3 value:4

2.1.5 Struct

Go中的struct关键字和C#中的作用是相同的,即定义一个结构体。因为Go中是没有类这个概念的,所以struct就相当于是C#中class的定义。同样的,struct在Go中是值类型结构,因此使用的时候一定需要注意案值传递导致的复制问题。(需要注意的是Go中的struct只能定义字段,不能定义函数。)

// struct的定义是配合type关键字一起使用的

type People struct {

name string // 定义的字段和Go语言其他的风格相同,名字在前,类型在后

age int

}

2.2Go与C#不一样但使用方法差不多的关键字

  • package
  • import
  • type
  • defer

2.2.1.Package与namespace

Go中的package和C#的namespace基本相同,就是定义组织的一个包,主要作用是对代码模块进行隔离。但Go和C#不同的是,C#十分灵活,即使不在一个文件夹下的代码都可以定义为相同的namespace。但是Go中package内的文件都需要在相同的文件夹内才能被正确编译,并且一个文件夹内只能出现最多一个包名。除此之外,类似于C#中的Main方法,Go中可运行程序的执行入口也是一个 main函数,但是main函数必须定义在package main下。

// Go中,同一个文件夹只能同时存在一个包名

// 包名可以和文件夹名不同,但是必须有且只有一个

package main

// main函数只能在main包下才能正确作为启动函数运行

func main() {

//do something

}

// 同文件夹下的另一个文件,比如hello.go

package hello //编译器报错

2.2.2.Import与using

Import和using的作用都是用来导入其他模块的代码。但是Go比C#多了一个强制要求:没有在代码模块中使用import或者是定义了但是没有使用的变量,在编译时会直接报错。这样做的目的除了使代码看起来更简洁以外,最主要的原因是import语句还有另一个重要功能就是调用包中的init()函数。例如如下代码:

// hello文件夹下的demo文件夹内的 demo.go

package demo

var me string

func init() {

me = "jeffery"

}

func SayHello() {

fmt.Printf("hello, %s", me)

}

// hello文件夹下的hello.go

package main

import "hello/demo"

func main() {

demo.SayHello() // 输出:hello, jeffery

}

上述的程序定义了一个demo文件,当demo文件第一次被import关键字加载到其他包时,会自动调用其init()函数,这时就会把变量me赋值为jeffery,之后调用SayHello()函数时,返回的就都是”hello, jeffery”了。也正是因为init函数的存在,不使用的import需要被删除,因为如果不删除很有可能会自动调用到未被使用的包内的 init 函数。

2.2.3. Type与class

  • 常规用法

把 type和class 对比其实是不太合理的。因为 C#中class关键字是定义一个类型和这个类型的具体实现,比如下述的代码在 C#中的意思是定义一个名为People的类,并且定义了这类中有一个属性 Age。

interface IAnimal {

public void Move();

}

class People {

public int Age { get;set; }

}

然而Go中的type关键字仅仅是用来定义类型名称的,如果想要定义其实现,必须后面再更上具体实现的关键字。比如上述的代码定义在Go中就变成了如下:

type IAnimal interface {

Move()

}

type People struct {

Age int

}

上述只是 type 的最常用用法,除此之外 type 还有两个其他的用法:

  • 以一个基准类型定义一个新类型
type Human People

这样的语句相当于用People类型定义了一个Human的新类型。注意,这里是一个新类型,而不是 C#中的继承。因此如果People内有一个Move函数,那Human对象是无法调用这个Move函数的,如果非要使用,则需要强制类型转换。(Go中的强制类型转换是类型+ (),比如上述的例子 Human(People)就可以把 People 类型强转为 Human 类型)

  • 定义类型别名
type Human = People

如果使用了等号进行定义,那就相当于给类型 People 定义了一个别名 Human,这种情况下 People 中的代码 Human 也是可以正常使用的。上面两种用法基本都不常用,这里只做了解即可。

2.2.4.Defer与finally

Go中的defer和C#的finally是一样的,在一个方法执行结束退出之前只可以干一件事。而和 C#不太一样的是,Go中的 defer 语句不用必须写在最后,比如我们会经常看到这样风格的代码:

var mutex sync.Mutex // 一个全局锁,可以类似的等价于C#中的Monitor类

func do() {

mutex.Lock()

defer mutex.Unlock()

// ...

}

上面这个例子的意思是定义一个全局锁,在do函数进入时,加锁,在退出时解锁。之后再去写自己的业务逻辑。除此之外,defer也可以写多个,但最终的执行顺序是从下向上执行,也就是最后定义的defer先执行。

2.3Go有而 C#没有的关键字

  • fallthrough
  • func

2.3.1. Fallthrough

这个关键字是为了兼容C语言中的 fallthrough,其目的是是在 switch-case 语句中再向下跳一个case,比如下面这个例子:

switch n := "a"; n {

case n == "a":

fmt.Println("a")

fallthrough

case n == "b":

fmt.Println("b")

case n == "c":

fmt.Println("c")

}

这个例子的最终输出结果就是:

a

b
### 2.3.2.Func

和其他函数(比如 JavaScript 的 function,Python 中的 def)一样,Go中的 func就是用来定义函数的。

// 定义了一个函数名称为getName的函数

// 其中包含一个int类型的参数id

// 以及两个返回值,string和bool类型

func getName(id int) (string, bool) {

return "jeffery", true

}

Go中的函数以及其他一系列需要定义类型的语法中,永远都遵循名称在前,类型在后。此外,Go中的func同样也可以配合type使用定义C#中的委托,比如我们可以在 C#中定义一个.Net Core 的中间件:

public delegate void handleFunc(HttpContext httpContext);

public delegate handleFunc middleware(handleFunc next);

这样的代码可以在 Go中这样实现:

type handleFunc func(httpContext HttpContext)

type middleware func(next handleFunc) handleFunc

3.文章小结

Go语言相较于C#在关键字上的优点有以下几个:

1.更简洁的语法:Go语言致力于简化代码的编写和理解,使得语言关键字的数量更少,更加简洁明了。相比之下,C#拥有更多的关键字,从而使代码的可读性稍微降低。

2.更好的并发性支持:Go语言天然支持并发编程,通过goroutine和channel管道,可以轻松实现高并发的程序。而C#对于并发编程需要手动处理锁,信号量等机制来控制线程的并发,代码比较繁琐。

3.更好的内存管理:Go语言使用垃圾回收机制,不需要开发者手动管理内存,避免了许多内存泄漏等问题。相比之下,C#需要开发者手动进行内存管理,需要使用using关键字或者手动释放内存等机制来控制内存,这增加了代码的复杂性。

4.更好的性能:由于采用了更简洁的语法和更好的内存管理,Go语言编写的程序具有更好的性能表现。与C#相比,Go语言的程序不仅运行速度更快,而且资源消耗更少,性能更出色。

4.扩展链接

如何使用 Blazor 框架在前端浏览器中导入/导出 Excel XLSX

万物皆可集成系列:低代码对接微信小程序

C#编写服务器端API

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

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

相关文章

ppt怎么录制视频和声音 ppt怎么录制人像

ppt在课堂上是非常重要的工具&#xff0c;许多微课都是通过ppt讲授。ppt的功能日新月异&#xff0c;之前的ppt仅具有演示功能&#xff0c;如今pp录制视频t还是可以的。ppt怎么录制视频和声音&#xff1f;首先&#xff0c;我们得创建一个ppt&#xff0c;然后再进行录制。ppt怎么…

【Python 随练】分解质因数

题目&#xff1a; 将一个正整数分解质因数。例如&#xff1a;输入 90,打印出90233*5。 简介&#xff1a; 在本篇博客中&#xff0c;我们将解决一个数学问题&#xff1a;如何将一个正整数分解成质因数的乘积。我们将给出问题的解析&#xff0c;并提供一个完整的代码示例来实现…

【Python】解决pandas读取excel,以0向前填充的数字会变成纯数字

1 问题 test.xlsx的内容如下 序号code000012310001242000125 df pd.read_excel(test.xlsx)读取后的codel列&#xff0c;样例如下 序号code012311242125 显然这不是我想要的结果。 2 解决办法 &#xff08;1&#xff09;第一种 指定列以字符串读取 df pd.read_excel(t…

在 ZBrush、Blender 和 Substance 3D Painter 中重新创建 Bowser

今天瑞云渲染小编给大家带来一篇mral Ismayilov作者Bowser 项目背后的工作流程&#xff0c;展示了头发是如何修饰的&#xff0c;并解释了纹理化过程。 简介 大家好&#xff0c;我是尤姆拉尔-伊斯马伊洛夫&#xff0c;是一名3D角色艺术家和动作设计师&#xff0c;在阿塞拜疆的巴…

【CMake 入门与进阶(10)】 CMake如何定义函数,内部参数及作用域(附代码)

前几篇已经学习了cmake 中常用的命令 command、变量 variable &#xff0c;相信大家已经掌握了 cmake 工具的基本使用方法&#xff1b;本文我们进一步学习 cmake&#xff0c;看看 cmake 还有哪些东西。 定义函数 在 cmake 中我们也可以定义函数&#xff0c;cmake 提供了 funct…

基于图神经网络的切片级漏洞检测及解释方法

源自&#xff1a;软件学报 作者&#xff1a;胡雨涛 王溯远 吴月明 邹德清 李文科 金海 摘 要 随着软件的复杂程度越来越高, 对漏洞检测的研究需求也日益增大. 软件漏洞的迅速发现和修补, 可以将漏洞带来的损失降到最低. 基于深度学习的漏洞检测方法作为目前新兴的检测手…

云原生之深入解析Kubernetes中Kubectl Top是如何进行资源监控

一、Kubectl top 的使用 kubectl top 是基础命令,但是需要部署配套的组件才能获取到监控值:1.8 以下:部署 heapter;1.8 以上:部署 metric-server;kubectl top node:查看 node 的使用情况:kubectl top pod:查看 pod 的使用情况:不指定 pod 名称,则显示命名空间下所有…

TSception:从EEG中捕获时间动态和空间不对称性用于情绪识别

TSception&#xff1a;从EEG中捕获时间动态和空间不对称性用于情绪识别&#xff08;论文复现&#xff09; 摘要模型结构代码实现写在最后 **这是一篇代码复现&#xff0c;原文通过Pytorch实现&#xff0c;本文中使用Keras对该结构进行复现。**该论文发表在IEEE Transactions on…

【Python 随练】古典问题:兔子繁殖问题

题目&#xff1a; 古典问题&#xff1a;有一对兔子&#xff0c;从出生后第 3 个月起每个月都生一对兔子&#xff0c;小兔子长到第三个月&#xff0c;后每个月又生一对兔子&#xff0c;假如兔子都不死&#xff0c;问每个月的兔子总数为多少&#xff1f; 简介&#xff1a; 在本…

三、DSMP/OLS等夜间灯光数据贫困地区识别——MPI和灯光指数拟合、误差分析

一、前言 当我们准备好MPI和灯光指数(包括总灯光指数和平均灯光指数)之后,接下来主要的过程就是通过将MPI和灯光指数拟合,构建多维度指数估算模型,这里我解释一下前文中的MPI计算过程,其实利用熵值法确定指标权重,并通过各 指 标 归 一 化 数 值 乘 以 对 应 的 权 重 …

UG NX二次开发(C#)-用UFun函数导出图像(Image)

文章目录 1、前言2、在UG NX中交互导出图像的操作2.1 打开一个三维模型2.2 打开导出图像的界面3、采用UFun函数来实现3.1 搜索image的方法3.2 帮助说明3.3 应用环境3.4 方法应用4、后记1、前言 在UG NX二次开发过程中,三维CAD模型有时需要导出为图像,如.png、.jpg、.bmp、.t…

类与封装的概念

类通常分为以下两个部分 类的实现细节 类的使用方式 当使用类时&#xff0c;不需要关心其实现细节 当创建类时&#xff0c;才需要考虑其内部实现细节 封装的基本概念 根据经验&#xff1a;并不是类的每个属性都是对外公开的 如&#xff1a;女孩子不希望外人知道自己的体重…

【系统开发】尚硅谷 - 谷粒商城项目笔记(二):搭建分布式系统基本环境

文章目录 搭建分布式系统基本环境引入spring-cloud-alibaba依赖Nacos作为注册中心Feign 远程调用Nacos作为配置中心Nacos配置中心进阶Nacos加载多配置集GateWay网关网关路由分发解释 搭建分布式系统基本环境 引入spring-cloud-alibaba依赖 在common的pom.xml中加入 &#xff…

Socket网络通信过程 与 IO多路复用原理

0、引言 本文主要讲述Socket网络编程的基本知识、IO多路复用的select、poll、epoll实现原理以及比较&#xff0c;并解答了一些socket建立连接、阻塞的常见问题。 1、什么是Socket、网络通信的过程 Socket 的中文名叫作插口&#xff0c;事实上&#xff0c;双方要进行网络通信前…

HTML(一)

一.HTML的标准结构 <!doctype html> 声明文档类型<html> HTML根标签<head> 头标签<title></title> 标题标签</head><body> 主题标签...</body></html> 二.标签介绍 2.1 段落标签 1.注释标签 <!--我是一个注释--…

送外卖适合什么蓝牙耳机,推荐几款适合户外佩戴的骨传导耳机

骨传导耳机&#xff0c;是通过震动的方式将声音转化为不同频率的机械振动&#xff0c;由于不需要通过耳膜就可以听到声音&#xff0c;骨传导耳机在保留传统耳机的优点的基础上&#xff0c;解决了传统耳机不能在开放环境中使用的问题。那么在骨传导耳机中&#xff0c;究竟有哪些…

MobaXterm 常用设置

MobaXterm 是用于远程计算的工具箱&#xff0c;作为一个 Windows 应用程序&#xff0c;它为程序员、网站管理员、IT管理员和几乎所有需要以更简单的方式处理远程工作的用户量身定制了大量功能。MobaXterm 提供了所有重要的远程网络工具(SSH, X11, RDP, VNC, FTP, MOSH&#xff…

消息队列常见问题整理

前言 消息队列&#xff08;Message Queue&#xff09;&#xff0c;从广义上讲是一种消息队列服务中间件&#xff0c;提供一套完整的信息生产、传递、消费的软件系统。 消息队列所涵盖的功能远不止于队列&#xff08;Queue&#xff09;&#xff0c;其本质是两个进程传递信息的…

Java Web程序设计的学习

属于B/S结构、服务器软件&#xff1a;Apache Tomcat、 Web 项目 目录结构&#xff1a; 1.src目录&#xff1a;存放Java源文件 2.WebRoot目录&#xff1a; 存在两个子目录&#xff1a; META-INF目录 WEB-INF目录&#xff1a;&#xff08;lib目录&#xff1a;存放驱动…

Notepad++安装json插件

Notepad是Windows操作系统下的一套文本编辑器(软件版权许可证:GPL)&#xff0c;有完整的中文化接口及支持多国语言编写的功能(UTF8技术)。 Notepad功能比 Windows 中的Notepad(记事本)强大&#xff0c;除了可以用来制作一般的纯文字说明文件&#xff0c;也十分适合编写计算机程…