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
является "значением указателя".