mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2024-12-26 06:46:27 +00:00
ch13: fix code path
This commit is contained in:
parent
8b7a8ea019
commit
617ef87432
@ -18,9 +18,8 @@ fmt.Printf("%#016x\n", Float64bits(1.0)) // "0x3ff0000000000000"
|
|||||||
|
|
||||||
許多將unsafe.Pointer指針轉爲原生數字,然後再轉迴爲unsafe.Pointer類型指針的操作也是不安全的。比如下面的例子需要將變量x的地址加上b字段地址偏移量轉化爲`*int16`類型指針,然後通過該指針更新x.b:
|
許多將unsafe.Pointer指針轉爲原生數字,然後再轉迴爲unsafe.Pointer類型指針的操作也是不安全的。比如下面的例子需要將變量x的地址加上b字段地址偏移量轉化爲`*int16`類型指針,然後通過該指針更新x.b:
|
||||||
|
|
||||||
|
<u><i>gopl.io/ch13/unsafeptr</i></u>
|
||||||
```Go
|
```Go
|
||||||
//gopl.io/ch13/unsafeptr
|
|
||||||
|
|
||||||
var x struct {
|
var x struct {
|
||||||
a bool
|
a bool
|
||||||
b int16
|
b int16
|
||||||
@ -66,5 +65,3 @@ func (Value) Pointer() uintptr
|
|||||||
func (Value) UnsafeAddr() uintptr
|
func (Value) UnsafeAddr() uintptr
|
||||||
func (Value) InterfaceData() [2]uintptr // (index 1)
|
func (Value) InterfaceData() [2]uintptr // (index 1)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@ fmt.Println(reflect.DeepEqual(c, d)) // "false"
|
|||||||
|
|
||||||
我們希望在這里實現一個自己的Equal函數,用於比較類型的值。和DeepEqual函數類似的地方是它也是基於slice和map的每個元素進行遞歸比較,不同之處是它將nil值的slice(map類似)和非nil值但是空的slice視作相等的值。基礎部分的比較可以基於reflect包完成,和12.3章的Display函數的實現方法類似。同樣,我們也定義了一個內部函數equal,用於內部的遞歸比較。讀者目前不用關心seen參數的具體含義。對於每一對需要比較的x和y,equal函數首先檢測它們是否都有效(或都無效),然後檢測它們是否是相同的類型。剩下的部分是一個鉅大的switch分支,用於相同基礎類型的元素比較。因爲頁面空間的限製,我們省略了一些相似的分支。
|
我們希望在這里實現一個自己的Equal函數,用於比較類型的值。和DeepEqual函數類似的地方是它也是基於slice和map的每個元素進行遞歸比較,不同之處是它將nil值的slice(map類似)和非nil值但是空的slice視作相等的值。基礎部分的比較可以基於reflect包完成,和12.3章的Display函數的實現方法類似。同樣,我們也定義了一個內部函數equal,用於內部的遞歸比較。讀者目前不用關心seen參數的具體含義。對於每一對需要比較的x和y,equal函數首先檢測它們是否都有效(或都無效),然後檢測它們是否是相同的類型。剩下的部分是一個鉅大的switch分支,用於相同基礎類型的元素比較。因爲頁面空間的限製,我們省略了一些相似的分支。
|
||||||
|
|
||||||
|
<u><i>gopl.io/ch13/equal</i></u>
|
||||||
```Go
|
```Go
|
||||||
gopl.io/ch13/equal
|
|
||||||
func equal(x, y reflect.Value, seen map[comparison]bool) bool {
|
func equal(x, y reflect.Value, seen map[comparison]bool) bool {
|
||||||
if !x.IsValid() || !y.IsValid() {
|
if !x.IsValid() || !y.IsValid() {
|
||||||
return x.IsValid() == y.IsValid()
|
return x.IsValid() == y.IsValid()
|
||||||
@ -125,5 +125,3 @@ fmt.Println(Equal(a, c)) // "false"
|
|||||||
**練習 13.1:** 定義一個深比較函數,對於十億以內的數字比較,忽略類型差異。
|
**練習 13.1:** 定義一個深比較函數,對於十億以內的數字比較,忽略類型差異。
|
||||||
|
|
||||||
**練習 13.2:** 編寫一個函數,報告其參數是否循環數據結構。
|
**練習 13.2:** 編寫一個函數,報告其參數是否循環數據結構。
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,9 +41,8 @@ bzip2壓縮算法,是基於優雅的Burrows-Wheeler變換算法,運行速度
|
|||||||
|
|
||||||
我們可以在Go代碼中直接調用BZ2_bzCompressInit和BZ2_bzCompressEnd,但是對於BZ2_bzCompress,我們將定義一個C語言的包裝函數,用它完成眞正的工作。下面是C代碼,對應一個獨立的文件。
|
我們可以在Go代碼中直接調用BZ2_bzCompressInit和BZ2_bzCompressEnd,但是對於BZ2_bzCompress,我們將定義一個C語言的包裝函數,用它完成眞正的工作。下面是C代碼,對應一個獨立的文件。
|
||||||
|
|
||||||
|
<u><i>gopl.io/ch13/bzip</i></u>
|
||||||
```C
|
```C
|
||||||
gopl.io/ch13/bzip
|
|
||||||
|
|
||||||
/* This file is gopl.io/ch13/bzip/bzip2.c, */
|
/* This file is gopl.io/ch13/bzip/bzip2.c, */
|
||||||
/* a simple wrapper for libbzip2 suitable for cgo. */
|
/* a simple wrapper for libbzip2 suitable for cgo. */
|
||||||
#include <bzlib.h>
|
#include <bzlib.h>
|
||||||
@ -168,9 +167,8 @@ func (w *writer) Close() error {
|
|||||||
|
|
||||||
下面的bzipper程序,使用我們自己包實現的bzip2壓縮命令。它的行爲和許多Unix繫統的bzip2命令類似。
|
下面的bzipper程序,使用我們自己包實現的bzip2壓縮命令。它的行爲和許多Unix繫統的bzip2命令類似。
|
||||||
|
|
||||||
|
<u><i>gopl.io/ch13/bzipper</i></u>
|
||||||
```Go
|
```Go
|
||||||
gopl.io/ch13/bzipper
|
|
||||||
|
|
||||||
// Bzipper reads input, bzip2-compresses it, and writes it out.
|
// Bzipper reads input, bzip2-compresses it, and writes it out.
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@ -211,4 +209,3 @@ $ ./bzipper < /usr/share/dict/words | bunzip2 | sha256sum
|
|||||||
**練習 13.3:** 使用sync.Mutex以保證bzip2.writer在多個goroutines中被併發調用是安全的。
|
**練習 13.3:** 使用sync.Mutex以保證bzip2.writer在多個goroutines中被併發調用是安全的。
|
||||||
|
|
||||||
**練習 13.4:** 因爲C庫依賴的限製。 使用os/exec包啟動/bin/bzip2命令作爲一個子進程,提供一個純Go的bzip.NewWriter的替代實現(譯註:雖然是純Go實現,但是運行時將依賴/bin/bzip2命令,其他操作繫統可能無法運行)。
|
**練習 13.4:** 因爲C庫依賴的限製。 使用os/exec包啟動/bin/bzip2命令作爲一個子進程,提供一個純Go的bzip.NewWriter的替代實現(譯註:雖然是純Go實現,但是運行時將依賴/bin/bzip2命令,其他操作繫統可能無法運行)。
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user