經過例子學習 Go 和 Rust ---- IO Reader

IO操做是咱編程時常常會遇到的,兩種語言都提供了通用的Read方法,可讓咱從reader結構體裏面讀出數據。編程

Go

//io/io.go
type Reader interface {
    Read(p []byte) (n int, err error)
}

//bytes/reader.go
type Reader struct {
    s        []byte
    i        int64 // current reading index
    prevRune int   // index of previous rune; or < 0
}

// Read implements the io.Reader interface.
func (r *Reader) Read(b []byte) (n int, err error) {
    if r.i >= int64(len(r.s)) {
        return 0, io.EOF
    }
    r.prevRune = -1
    n = copy(b, r.s[r.i:])
    r.i += int64(n)
    return
}

能夠看出在 go 語言裏面某個類型是否實現了某個接口,是沒有顯示標註的,只要函數簽名相同,就能夠說是實現了這個接口。函數

a.Read(b)表示把a裏面的數據複製到b,並修改a裏的已讀座標。code

舉個栗子

import (
    "bytes"
)

func main() {
    reader := bytes.NewReader([]byte{1, 2, 3})
    target := make([]byte, 5)
    fmt.Println(reader, target)
    reader.Read(target)
    fmt.Println(reader, target)
}
&{[1 2 3] 0 -1} [0 0 0 0 0]
&{[1 2 3] 3 -1} [1 2 3 0 0]

Rust

pub trait Read {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
    
impl Read for &[u8] {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let amt = cmp::min(buf.len(), self.len());
        let (a, b) = self.split_at(amt);

        // First check if the amount of bytes we want to read is small:
        // `copy_from_slice` will generally expand to a call to `memcpy`, and
        // for a single byte the overhead is significant.
        if amt == 1 {
            buf[0] = a[0];
        } else {
            buf[..amt].copy_from_slice(a);
        }

        *self = b;
        Ok(amt)
    }

與 Go 語言裏的複製不一樣,這裏被read的時候,原始數據會被修改,只留下還未read的部分。接口

又舉個栗子

use std::io::Read;

fn main() {
    let mut reader: &[u8] = &[1, 2, 3][..];
    let target: &mut [u8] = &mut [0;5][..];
    reader.read(target);
    
    let empty_slice: &[u8] = &[][..];
    assert_eq!(reader, empty_slice);
    assert_eq!(target, &[1,2,3,0,0]);
}
相關文章
相關標籤/搜索