阿里云做网站需要些什么简单网页设计html代码
news/
2025/10/2 2:08:23/
文章来源:
阿里云做网站需要些什么,简单网页设计html代码,网站后台用什么软件做,网站开发团队人员配置Go语言入门
Go语言入门教程
很多人将 Go 语言 称为 21 世纪的 C 语言#xff0c;因为 Go 不仅拥有 C 语言的简洁和性能#xff0c;而且还很好的提供了 21 世纪互联网环境下服务端开发的各种实用特性#xff0c;让开发者在语言级别就可以方便的得到自己想要的东西。
在 Go…Go语言入门
Go语言入门教程
很多人将 Go 语言 称为 21 世纪的 C 语言因为 Go 不仅拥有 C 语言的简洁和性能而且还很好的提供了 21 世纪互联网环境下服务端开发的各种实用特性让开发者在语言级别就可以方便的得到自己想要的东西。
在 Go 语言的版本迭代过程中语言特性基本上没有太大的变化基本上维持在 Go1.1 的基准上并且官方承诺新版本对老版本下开发的代码完全兼容。事实上Go 开发团队在新增语言特性上显得非常谨慎而在稳定性、编译速度、执行效率以及 GC 性能等方面进行了持续不断的优化。
Go语言优缺点
优点
Go很容易学习
如果你了解任何一种编程语言那么通常在学习几个小时就能够掌握 Go 的大部分语法并在几天后写出你的第一个真正的程序。阅读并理解实效 Go 编程浏览一下包文档玩一玩 Gorilla 或者 Go Kit 这样的网络工具包然后你将成为一个相当不错的 Go 开发者。
这是因为 Go 的首要目标是简单。当我开始学习 Go它让我想起我第一次 发现 Java一个简单的语言和一个丰富但不臃肿的标准库。对比当前 Java 沉重的环境学习 Go 是一个耳目一新的体验。因为 Go 的简易性Go 程序可读性非常高虽然错误处理添加了一些麻烦。
简单并发编程
Goroutines 可能是 Go 的最佳特性了。它们是轻量级的计算线程与操作系统线程截然不同。当 Go 程序执行看似阻塞 I/O 的操作时实际上 Go 运行时挂起了 goroutine ,当一个事件指示某个结果可用时恢复它。与此同时其他的 goroutines 已被安排执行。因此在同步编程模型下我们具有了异步编程的可伸缩性优势。
Goroutines 也是轻量级的:它们的堆栈随需求增长和收缩这意味着有 100 个甚至 1000 个 goroutines 都不是问题。
channel 是 goroutines 的通信方式:它们提供了一个便利的编程模型可以在 goroutines 之间发送和接收数据而不必依赖脆弱的低级别同步基本体。channels 有它们自己的一套用法模式。但是channels 必须仔细考虑因为错误大小的 channels (默认情况下没有缓冲) 会导致死锁。下面我们还将看到使用通道并不能阻止竞争情况因为它缺乏不可变性。
丰富的标准库
Go 的标准库非常丰富特别是对于所有与网络协议或 API 开发相关的: http 客户端和服务器加密档案格式压缩发送电子邮件等等。甚至还有一个 html 解析器和相当强大的模板引擎去生成 text html它会自动过滤 XSS 攻击例如在 Hugo 中的使用。
各种 APIs 一般都简单易懂。它们有时看起来过于简单:这个某种程度上是因为 goroutine 编程模型意味着我们只需要关心 “看似同步” 的操作。这也是因为一些通用的函数也可以替换许多专门的函数就像 我最近发现的关于时间计算的问题。
Go性能优越
Go 编译为本地可执行文件。许多 Go 的用户来自 Python、Ruby 或 Node.js。对他们来说这是一种令人兴奋的体验因为他们看到服务器可以处理的并发请求数量大幅增加。当您使用非并发(Node.js)或全局解释器锁定的解释型语言时这实际上是相当正常的。结合语言的简易性这解释了 Go 令人兴奋的原因。
然而与 Java 相比在原始性能基准测试中情况并不是那么清晰。Go 打败 Java 地方是内存使用和垃圾回收。Go 的垃圾回收器的设计目的是优先考虑延迟并避免停机这在服务器中尤其重要。这可能会带来更高的 CPU 成本但是在水平可伸缩的体系结构中这很容易通过添加更多的机器来解决。请记住Go 是由谷歌设计的他们从不会在资源上面短缺。
与 Java 相比Go 的垃圾回收器GC需要做的更少:切片是一个连续的数组结构而不是像 Java 那样的指针数组。类似地Go maps 也使用小数组作为 buckets以实现相同的目的。这意味着垃圾回收器的工作量减少并且 CPU 缓存本地化也更好。
标准化的测试框架
Go 在其标准库中提供了一个很好的测试框架。它支持并行测试、基准测试并包含许多实用程序可以轻松测试网络客户端和服务器。
缺点
Go忽略了现代语言设计的进步
在少既是多中Rob Pike 解释说 Go 是为了在谷歌取代 C 和 C它的前身是 Newsqueak 这是他在 80 年代写的一种语言。Go 也有很多关于 Plan9 的参考Plan9 是一个分布式操作系统在贝尔实验室的 80 年代开发的。
甚至有一个直接从 Plan9 获得灵感的 Go 汇编。为什么不使用 LLVM 来提供目标范围广泛且开箱即用的体系结构?我此处可能也遗漏了某些东西但是为什么需要汇编?如果你需要编写汇编以充分利用 CPU 那么不应该直接使用目标 CPU 汇编语言吗?
Go 的创造者应该得到尊重但是看起来 Go 的设计发生在平行宇宙或者他们的 Plan9 lab?中发生的这些编译器和编程语言的设计在 90 年代和 2000 年中从未发生过。也可能 Go 是由一个会写编译器的系统程序员设计的。
函数式编程吗不要提它。泛型你不需要看看他们用 C 编写的烂摊子!尽管 slice、map 和 channel 都是泛型类型我们将在下面看到。
Go 的目标是替换 C 和 C很明显它的创建者也没有关注其他地方。但他们没有达到目标因为在谷歌的 C 和 C 开发人员没有采用它。我的猜测是主要原因是垃圾回收器。低级别 C 开发人员强烈拒绝托管内存因为他们无法控制什么时间发生什么情况。他们喜欢这种控制即使它带来了额外的复杂性并且打开了内存泄漏和缓冲溢出的大门。有趣的是Rust 在没有 GC 的情况下采用了完全不同的自动内存管理方法。
Go 反而在操作工具的领域吸引了 Python 和 Ruby 等脚本语言的用户。他们在 Go 中找到了一种方法可以提高性能减少 内存/cpu/磁盘 占用。还有更多的静态类型这对他们来说是全新的。Go 的杀手级应用是 Docker 它在 devops 世界中引起了广泛的应用。Kubernetes 的崛起加强了这一趋势。
接口是结构类型
Go 接口 就像 Java 接口或 Scala 和 Rust 特性traits:它们定义了后来由类型实现的行为我不称之为“类”。与 Java 接口和 Scala 和 Rust 特性不同类型不需要显式地指定接口实现:它只需要实现接口中定义的所有函数。所以 Go 的接口实际上是结构化的。
我们可能认为这是为了允许其他包中的接口实现而不是它们适用的类型比如 Scala 或 Kotlin 中的类扩展或 Rust 特性但事实并非如此:所有与类型相关的方法都必须在类型的包中定义。
没有枚举
Go 没有枚举在我看来这是一个错失的机会。iota 可以快速生成自动递增的值但它看起来更像一个技巧 而不是一个特性。实际上由于在一系列的 iota 生成的常量中插入一行会改变下列值的值这是很危险的。由于生成的值是在整个代码中使用的值因此这会导致有趣的而不是!意外。
这也意味着没有办法让编译器彻底检查 switch 语句也无法描述类型中允许的值。
没有泛型
很难想象一种没有泛型的现代静态类型化语言但这就是你在 Go 中看到的:它没有泛型…或者更精确地说几乎没有泛型我们会看到它比没有泛型更糟糕。
内置的 slice、map、array 和 channel 都是泛型。声明一个 map[string]MyStruct 清楚地显示了具有两个参数的泛型类型的使用。这很好因为它允许类型安全编程捕获各种错误。
然而没有用户可定义的泛型数据结构。这意味着您不能定义可重用的抽象它可以以类型安全的方式使用任何类型。您必须使用非类型 interface{}并将值转换为适当的类型。任何错误只会在运行时被抓住会导致 panic。对于 Java 开发人员来说这就像回到 回退 Java 5 个版本到 2004 年。
Go语言基础
基本数据类型
变量和常量
普通赋值:
// var 变量名称 变量类型 值
var num int 1平行赋值:
var num1,num2 int 1, 2多行赋值
var (num1 int 1num2 int 2
)整数类型的命名和宽度
Go 的 整数类型 一共有 10 个其中计算架构相关的整数类型有两个即有符号的整数类型 int 和无符号的整数类型 uint。在不同计算架构的计算机上它们体现的宽度(存储某个类型的值所需要的空间)是不一样的。空间的单位可以是 bit 也可以是字节 byte。 除了这两个计算架构相关的整数类型之外还有 8 个可以显式表达自身宽度的整数类型: 整数类型值的表示法 如果以 8 进制为变量 num 赋值:
num 039 // 用0作为前缀以表明这是8进制表示法如果以 16 进制为变量 num 赋值:
num 0x39浮点类型
浮点数 类型有两个float32/float64。浮点数类型的值一般由整数部分、小数点 “.” 和小数部分组成。另外一种表示方法是在其中加入指数部分。指数部分由 “E” 或 “e” 以及带正负号的 10 进制整数表示。
复数类型
复数类型有两个:complex64 和 complex128。实际上complex64 类型的值会由两个 float32 类型的值分别表示复数的实数部分和虚数部分。而 complex128 类型的值会由两个 float64 类型的值表示复数的实数部分和虚数部分。
byte与rune
byte 与 rune 都属于别名类型。byte 是 uint8 的别名类型而 rune 是 int32 的别名类型。一个 rune 的类型值即可表示一个 Unicode 字符。一个 Unicode 代码点通常由 “U” 和一个以十六进制表示法表示的整数表示。
字符串类型
字符串 的表示法有两种即原生表示法和解释型表示法。原生表示法需用用反引号 “” 把字符序列包起来如果用解释型表示法则需要用双引号 “” 包裹字符序列。
var str1 string “str”
var str1 string str二者的区别是前者表示的是所见即所得的(除了回车符)。后者所表示的值中转义符会起作用。字符串值是不可变的如果我们创建了一个此类型的值就不可能再对它本身做任何修改。
数组类型
一个数组是可以容纳若干相同类型的元素的容器。数组的长度是固定的。如下声明一个数组类型:
type MyNumbers [3]int类型声明语句由关键字 type、类型名称和类型字面量组成上面这条类型声明语句实际上是为数组类型 [3]int 声明了一个别名类型。这使得我们可以把 MyNumbers 当作数组类型 [3]int 来使用。
我们表示这样一个数组类型的值的时候。应该把该类型的类型字面量写在最左边然后用花括号包裹该值包含的若干元素各元素之间以(英文半角)逗号分割即:
[3]int{1,2,3}现在我们把这个数组字面量赋给一个名为 numbers 的变量:
var numbers [3]int{1,2,3}这是一条变量声明语句它在声明变量的同时为该变量赋值另一种方式是在其中的类型字面量中省略代表其长度的数组例
var numbers [...]int{1,2,3}可以用如下方式访问该变量中的任何一个元素。例:
numbers[0]
numbers[1]
numbers[2]如果要修改数组值中的某一个元素值可以
numbers[1] 4可以用如下方式获取数组长度:
var length len(numbers)如果一个数组没有赋值则它的默认值为
[length]type{0,0,0…}切片类型
切片(slice)与数组一样也是可以若干相同类型元素的容器。与数组不同的是切片类型的长度不确定。每个切片值都会将数组作为其底层数据结构。表示切片类型的字面量如:
[]int或者是:
[]string切片类型的声明可以这样:
type MySlice []int对切片值的表示也与数组值相似
[]int{1,2,3}操作数组值的方法同样适用于切片值。还有一种操作数组的方式叫做“切片”实施切片操作的方式就是切片表达式。例:
var number3 [5]int{1,2,3,4,5}
var slice1 numbers3[1:4]上例中切片表达式 numbers3[1:4] 的结果为 []int{2,3,4} 很明显被切下的部分不包含元素上界索引指向的元素。实际上 slice1 这个切片值的底层数组正是 number3 的值。我们也可以在切片值上实施切片操作
var slice2 slice1[1:3]除了长度切片值以及数组值还有另外一个属性–容量。数组的容量总是等于其长度而切片值的容量往往与其长度不同。如下图: 如图所示一个切片值的容量即为它的第一个元素值在其底层数组中的索引值与该数组长度的差值的绝对值。可以使用cap()内建函数获取数组、切片、通道类型的值的容量:
var capacity2 int cap(slice2)切片类型属于引用类型它的零值即为 nil即空值。如果我们只声明了一个切片类型而不为它赋值则它的默认值 nil。切片的更多操作方法有些时候我们可以在方括号中放入第三个正整数。
numbers3[1:4:4]第三个正整数为容量上界索引它意义在于可以把作为结果的切片值的容量设置的更小。它可以限制我们通过这个切片值对其底层数组中的更多元素的访问。上节中 numbers3 和 slice 的赋值语句如下:
var numbers3 [5]int{1,2,3,4,5}
var slice1 numbers3[1:4]这时变量 slice1 的值是 []int{2,3,4}。但是我们可以通过如下操作将其长度延展与其容量相同:
slice1 slice1[:cap(slice1)]通过此操作变量 slice1 的值变为了 []int{2,3,4,5}且其长度和容量均为 4。现在 number3 的值中的索引值在 (1,5) 范围内的元素都被体现在了 slice1 的值中。这是以 number3 的值是 slice1 的值的底层数组为前提的。
这意味着我们可以轻而易举地通过切片访问其底层数组中对应索引值更大的更多元素。如果我们编写的函数返回了这样一个切片值那么得到它的程序很可能会通过这种技巧访问到本不应该暴露给它的元素。如果我们在切片中加入了第三个索引(即容量上限索引)如
var slice1 numbers3[1:4:4]那么在此之后我们将无法通过 slice1 访问到 number3 的值中的第五个元素。虽然切片值在上述方面受到了其容量的限制。但是我们可以通过另外一种手段对其进行不受限制的扩展。这需要用到内建函数 append。append 会对切片值进行扩展并返回一个新的切片值使用方法如下:
slice1 append(slice1, 6, 7)通过上述操作slice1 的值变为了 []int{2,3,4,6,7}。一旦扩展操作超出了被操作的切片值的容量那么该切片的底层数组就会被替换。最后一种操作切片的方式是 “复制”。该操作的实施方法是调用 copy 函数。
该函数接收两个类型相同的切片值作为参数并把第二个参数值中的元素复制到第一个参数值中的相应位置(索引值相同)上。这里有两点需要注意:这种复制遵循最小复制原则即被复制的元素的个数总是等于长度较短的那个参值的长度。 与 append 函数不同copy 函数会直接对其第一个参数值进行修改。
var slice4 []int{0,0,0,0,0,0}
copy(slice4, slice1)通过上述复制操作slice4 会变成 []int{2,3,4,6,7,0,0}。
字典类型
Go 语言的字典(Map)类型是一个哈希表的实现。字典类型的字面量如下:
map[K]T其中“K” 为键的类型而 “T” 则代表元素(值)的类型。如果我们描述一个键类型为 int值类型为 string 的字典类型的话
map[int]string字典的键类型必须是可比较的否则会引起错误即键不能是切片、字典、函数类型。
字典值的字面量表示法实际上与数组的切片的字面量表示法很相似。最左边仍然是类型字面量右边紧挨着由花括号包裹且有英文逗号分隔的键值对。每个键值对的键和值之间由冒号分隔。以字典类型 map[int]string 为例。他的值的字面量可以是这样的
map[int]string{1:a,2:bm,3:c}我们可以把这个值赋给一个变量
mm : map[int]string{1:a,2:b,3:c}可用索引表达式取出字典中的值
b : mm[2]可以用索引表达式赋值:
mm[2] b 2这样 mm 中键为 2 的值变为了 “b2”。可以用如下方式向字典中添加一个键值对:
mm[4] 对于字典值来说如果指定键没有对应的值则默认为该类型的空值。所以 mm[5] 会返回一个 “”。但是这样的话我们就不知道 mm[5] 到底是 “” 还是 mm[5] 没有这个值。所以 go 提供了另外一种写法:
e, ok : mm[5]针对字典的索引表达式可以有两个求职结果第二个求职结果是 bool 类型的。它用于表明字典值中是否存在指定的键值对。 从字典中删除键值对的方法非常简单仅仅是调用内建函数 delete
delete(mm, 4)无论 mm 中是否存在以 4 为键的键值对delete 都删除。 字典类型属于引用类型它的零值即为 nil。
通道类型
通道(Channel)是 Go 语言中一种非常独特的数据结构。它可用于在不同 Goroutine 之间传递类型化的数据。并且是并发安全的。相比之下之前几种数据类型都不是并发安全的。
Goroutine 可以被看作是承载可被并发执行的代码块的载体。它们由 Go 语言的运行时系统调度并依托操作系统线程(又称内核线程)来并发地执行其中的代码块。
通道类型的表示方法很简单仅由两部分组成:
chan T在这个类型字面量中左边是代表通道类型的关键字 chan而右边则是一个可变的部分即代表该通道类型允许传递的数据的类型(或称通道的元素类型)。
与其他的数据类型不同我们无法表示一个通道类型的值因此我们无法用字面量来为通道类型的变量赋值。只能通过调用内建函数 make 来达到目的。make 参数可接受两个参数第一个参数是代表了将被初始化的值的类型的字面量(例: chan int),而第二个参数则是值的长度例如,若我们想要初始化一个长度为 5 且元素类型为int的通道值则需要这样写:
make(chan int, 5)make 函数也可以被用来初始化切片类型或字典类型的值。暂存在通道值中的数据是先进先出。下面我们声明一个通道类型的变量并为其赋值:
ch1 : make(chan string, 5)这样一来我们就可以使用接受操作符 - 向通道值发送数据了。当然也可以使用它从通道值接收数据例如如果我们要向通道 ch1 发送字符串 “value1”那么应该这样做:
ch1 - “value1如果我们从 ch1 那里接收字符串则要这样:
- ch1我们可以把接受到字符串赋给一个变量如:
value : - ch1与针对字典值的索引表达式一样针对通道值的接受操作也可以有第二个结果值:
value, ok : - ch1这里的 ok 的值是 bool 类型的。它代表了通道值的状态true 代表通道值有效而 false 则代表通道值已无效(或称已关闭)更深层次的原因是如果在接受操作进行之前或过程中通道值被关闭了则接收操作会立即结束并返回一个该通道值的元素类型的零值。
可以通过函数 close 来关闭通道:
close(ch1)对通道值的重复关闭会引发运行时异常会使程序崩溃。在通道值有效的前提下针对它的发送操作会在通道值已满(其中缓存的数据的个数已等于它的长度)时被阻塞。而向一个已被关闭的通道值发送数据会引发运行时异常。针对有效通道值的接收操作会在它已经为空时被阻塞。通道类型属于引用类型它的零值为 nil。
流程控制
条件语句
对应的关键字为 if、 else 和 else if
if a : 1; a 1 {fmt.Println(OK)
}选择语句
对应的关键字为 switch、 case 和 select
switch i {case 0:fmt.Printf(0)case 1:fmt.Printf(1)case 2:fallthroughcase 3:fmt.Printf(3)case 4, 5, 6:fmt.Printf(4, 5, 6)default:fmt.Printf(Default)
}循环语句
对应的关键字为 for 和 range
sum : 0
for i : 0; i 10; i {sum i
}跳转语句
func myfunc() {i : 0HERE:fmt.Println(i)iif i 10 {goto HERE}
}函数
概述
首先函数的格式是固定的func函数名 参数 返回值可选 函数体。例 :
func main {fmt.Println(Hello go)
}在 golang 中有两个特殊的 函数main 函数和 init 函数main 函数不用介绍在所有语言中都一样它作为一个程序的入口只能有一个。init 函数在每个 package 是可选的可有可无甚至可以有多个(但是强烈建议一个 package 中一个 init 函数)init 函数在你导入该 package 时程序会自动调用 init 函数所以 init 函数不用我们手动调用,另外它只会被调用一次因为当一个 package 被多次引用时它只会被导入一次。
参数传递 普通变量 使用普通变量作为函数参数的时候在传递参数时只是对变量值得拷贝即将实参的值复制给变参当函数对变参进行处理时并不会影响原来实参的值。 指针 函数的变量不仅可以使用普通变量还可以使用指针变量使用指针变量作为函数的参数时在进行参数传递时将是一个地址看呗即将实参的内存地址复制给变参这时对变参的修改也将会影响到实参的值。 数组 和其他语言不同的是go语言在将数组名作为函数参数的时候参数传递即是对数组的复制。在形参中对数组元素的修改都不会影响到数组元素原来的值。 slice, map, chan 在使用 slice, map, chan 作为函数参数时进行参数传递将是一个地址拷贝即将底层数组的内存地址复制给参数 slice, map, chan 。这时对 slice, map, chan 元素的操作就是对底层数组元素的操作。 函数名字 在 go 语言中函数也作为一种数据类型所以函数也可以作为函数的参数来使用。
返回值
go 语言可以返回局部变量的指针因为 go 语言的回收机制是当销毁栈上的临时数据且发现有被外部引用的栈上变量时会自动转移到堆上。
闭包
和其他语言类似golang 也支持闭包函数
package mainimport fmtfunc adder() func(int) int {sum : 0return func(x int) int {sum xreturn sum}
}func main() {pos, neg : adder(), adder()for i : 0; i 10; i {fmt.Println(pos(i),neg(-2*i),)}
}Go语言入门教程总结
很多人将 Go 语言称为 21 世纪的 C 语言因为 Go 不仅拥有 C 语言的简洁和性能而且还很好的提供了 21 世纪互联网环境下服务端开发的各种实用特性让开发者在语言级别就可以方便的得到自己想要的东西。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/924491.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!