os.Read () Как работа?Golang - PullRequest
       0

os.Read () Как работа?Golang

0 голосов
/ 06 июня 2018

Почему, если я печатаю bs, перед вызовом Read() он ничего не печатает, но после вызова file.Read(bs) показывает внутреннюю часть файла test.txt.Если bs является только аргументом, как Read() может его изменить?

package main
import (
"os"
"fmt"
)

func main() {
    file , err := os.Open("test.txt")
if err == nil {
} else {

}
stat , _ := file.Stat()


bs := make([]byte, stat.Size())
fmt.Println(string(bs))
bsf ,err := file.Read(bs)

if err != nil{
    fmt.Println(err)
    fmt.Println(bsf)
}
fmt.Println(string(bs))


} 

Вывод:

(Line1)                                           
(Line2)hi, This is Example text in test.txt file.

1 Ответ

0 голосов
/ 14 июня 2018

Если bs не является единственным аргументом, то как Read () может его изменить?

Возможно, вам не хватает базовых знаний о языках программирования в целом.Существуют разные виды «ценностей».Есть указатели (или ссылки) и есть «обычные значения».

Например:

package main

import (
    "fmt"
)

func changeIt(p *int) {
    *p = 9
}

func main() {
    a := 1
    fmt.Println(a)
    changeIt(&a)
    fmt.Println(a)
}

Будет напечатано 1 9, а не 1 1.*int не целое число, а указатель на целое число.Указатель - это значение, которое указывает (ссылается) на другое значение.Если у вас есть значение указателя типа, вы получите фактическое значение, на которое указывает указатель, используя * (который называется разыменованием):

func main() {
    a := 1
    b := &a
    fmt.Println(b, *b)
}

b - указатель (типа *int) это указывает на a.println напечатает местоположение a, за которым следует значение a, которое обычно что-то вроде uhm 0x10414020 1.Мы также можем изменить значение, на которое указывает указатель, используя *p = ...:

func main() {
    a := 1
    b := &a
    *b = 9
    fmt.Println(b, *b, a)
}

, который будет печатать 0x10414020 9 9.

Теперь, []byte - это слайс ... слайсыкак указатели.Когда вы делаете

func changeIt(buf []byte) {
    buf[0] = 10
}

func main() {
    data := []byte{1,2,3}
    changeIt(data)
    fmt.Println(data)
}

На самом деле вы не передаете значения [1 2 3] в changeIt, а указывает на эти значения.Таким образом, здесь println покажет [10 2 3].Сравните это с:

func changeIt(buf [3]byte) {
    buf[0] = 10
}

func main() {
    data := [3]byte{1,2,3}
    changeIt(data)
    fmt.Println(data)
}

, который напечатает [1 2 3] и передаст значения [1 2 3], а не указатель, поэтому changeIt по существу работает с копией, а buf[0] = 10 не имеет никакого эффекта.Помните: [n]T - это массив, []T - это фрагмент.[n]T является «необработанным значением», а []T является «значением указателя».

...