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

Почему, если я печатаю 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 ответ

Если 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 который обычно что-то вроде гм 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 является "значением указателя".

Другие вопросы по тегам