Go 网络开发中的常用的应用层协议库都是基于 net 标准库开发的,比如 gorilla/websocket 和 go-grpc,还有最常用的 http 库。
当请求一个不存在的 host 时会返回一个错误,如下所示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
$ cat main.go package main
import ( "fmt" "net/http" )
func main() { if _, err := http.Get("http://unknownhost.example"); err != nil { fmt.Println(err) } } $ go run main.go Get "http://unknownhost.example": dial tcp: lookup unknownhost.example: no such host
除了给域名颁发证书之外,还可以给 ip 颁发证书,可以访问 https://1.1.1.1 看到这个浏览器是正常的,并没有报错,下面去掉大部分信息后,可以看到证书给 ipv4 和 ipv6 都有颁发证书。
1 2 3 4 5 6 7 8 9 10 11
Certificate: Issuer: C=US, O=DigiCert Inc, CN=DigiCert ECC Secure Server CA Validity Not Before: Jan 28 00:00:00 2019 GMT Not After : Feb 1 12:00:00 2021 GMT Subject: C=US, ST=California, L=San Francisco, O=Cloudflare, Inc., CN=cloudflare-dns.com
X509v3 Subject Key Identifier: 70:95:DC:5C:A3:8E:66:07:DB:CB:81:10:C6:AB:E7:C3:A8:45:7F:A0 X509v3 Subject Alternative Name: DNS:cloudflare-dns.com, DNS:*.cloudflare-dns.com, DNS:one.one.one.one, IP Address:1.1.1.1, IP Address:1.0.0.1, IP Address:162.159.132.53, IP Address:2606:4700:4700:0:0:0:0:1111, IP Address:2606:4700:4700:0:0:0:0:1001, IP Address:2606:4700:4700:0:0:0:0:64, IP Address:2606:4700:4700:0:0:0:0:6400, IP Address:162.159.36.1, IP Address:162.159.46.1
// Subject Alternate Name values. (Note that these values may not be valid // if invalid values were contained within a parsed certificate. For // example, an element of DNSNames may not be a valid DNS domain name.) DNSNames []string EmailAddresses []string IPAddresses []net.IP // Go 1.1 URIs []*url.URL // Go 1.10
如果使用 CommonName 而没有 SAN ,HTTPS 是无法成功握手的。另外 common name 也可以填写其它任意的字符串,通用名称本质上已经成了一个名称,并没有特殊的作用了。
a?.b// undefined if `a` is null/undefined, `a.b` otherwise. a == null ? undefined : a.b
a?.[x] // undefined if `a` is null/undefined, `a[x]` otherwise. a == null ? undefined : a[x]
a?.b() // undefined if `a` is null/undefined a == null ? undefined : a.b() // throws a TypeError if `a.b` is not a function // otherwise, evaluates to `a.b()`
a?.() // undefined if `a` is null/undefined a == null ? undefined : a() // throws a TypeError if `a` is neither null/undefined, nor a function // invokes the function `a` otherwise
从这张图,然后我们再次分析下上一页的代码,由于 go 只有拷贝传递,所以 slice 内部的结构都会被赋值一份。当 append 的时候会插入一个元素,首先检查这里容量是否足够足够,这里因为直接定义的 slice 有两个元素,所以容量也是 2,所以会新开辟一块新的,然后函数内部 i 变量指向这块内存,而外部变量 i 还是指向原先的内存。