GOPL第七章練習題

7.1

使用來自ByteCounter的思路,實現一個針對對單詞行數的計數器golang

package main

import (
	"bufio"
	"bytes"
	"fmt"
)

type Counter struct {
	line int
	word int
}

//implement the io.Writer interface
func (c *Counter) Write(p []byte) (int, error) {
	line, err := counterLine(p)
	if err != nil {
		return 0, err
	}
	c.line += line
	word, err := counterWord(p)
	if err != nil {
		return 0, nil
	}
	c.word += word
	return len(p), nil
}

//implements the fmt.Stringer interface
func (c Counter) String() string {
	return fmt.Sprintf("Counter has %d words and %d lines!\n", c.word, c.line)
}

func main() {
	var str = "Spicy jalapeno pastrami ut ham turducken.\n " +
		"Lorem sed ullamco, leberkas sint short loin strip steak ut shoulder shankle porchetta venison prosciutto turducken swine.\n " +
		"Deserunt kevin frankfurter tongue aliqua incididunt tri-tip shank nostrud.\n"

	var c Counter
	fmt.Println(c)
	fmt.Fprintf(&c, str)
	fmt.Println(c)
}

//count the lines of the given strings
func counterLine(p []byte) (int, error) {
	scan := bufio.NewScanner(bytes.NewReader(p))
	scan.Split(bufio.ScanLines)
	var line int
	for scan.Scan() {
		line++
	}
	if err := scan.Err(); err != nil {
		return 0, err
	}
	return line, nil
}

//count the words of the given strings
func counterWord(p []byte) (int, error) {
	scan := bufio.NewScanner(bytes.NewReader(p))
	scan.Split(bufio.ScanWords)
	var word int
	for scan.Scan() {
		word++
	}
	if err := scan.Err(); err != nil {
		return 0, nil
	}
	return word, nil
}
//output:
//Counter has 0 words and 0 lines!
//Counter has 32 words and 3 lines!
複製代碼

7.2

寫一個帶有以下函數簽名的函數CountingWriter,傳入一個io.Writer接口類型,返回一個新的Writer類型把原來的Writer封裝在裏面和一個表示寫入新的Writer字節數的int64類型指針函數

package counter

import "io"

type byteWriter struct {
	w       io.Writer
	written int64
}

func (b *byteWriter) Write(p []byte) (n int, err error) {
	n, err = b.w.Write(p)
	b.written += int64(n)
	return 
}

func CounterWriter(writer io.Writer) (io.Writer, *int64)  {
	c := &byteWriter{w: writer, written: 0}
	return c, &c.written
}
複製代碼
package counter

import (
	"bytes"
	"testing"
)

func TestCounterWriter(t *testing.T) {
	b := &bytes.Buffer{}
	c, n := CounterWriter(b)
	data := []byte("Hello golang!")
	c.Write(data)
	if l := len(data); *n != int64(l) {
		t.Logf("%d != %d", *n, l)
		t.Fail()
	}
}
複製代碼
相關文章
相關標籤/搜索