Go đã làm tôi bối rối một lần nữa. Hy vọng rằng ai đó có thể giúp đỡ. Tôi đã tạo một slice (mySlice) có chứa các con trỏ tới các cấu trúc (myStruct).Cách xóa một mục khỏi một lát bằng cách gọi một phương thức trên slice
Sự cố là phương pháp "Xóa". Khi chúng ta ở bên trong "Remove" mọi thứ đều ổn, nhưng một khi chúng ta quay trở lại, kích thước slice đã không thay đổi, và vì vậy chúng ta thấy phần tử cuối cùng được liệt kê hai lần.
Ban đầu tôi đã thử viết "Xóa" bằng cách sử dụng cùng một mẫu được sử dụng trong phương thức "Thêm", nhưng nó sẽ không biên dịch và đã được nhận xét.
Tôi có thể làm cho nó hoạt động bằng cách trả lại lát mới được tạo cho hàm gọi, nhưng tôi không muốn làm điều này vì mySlice (ms) là một singleton.
Và nếu tôi không hỏi đủ đã ...
Mã cho phương pháp "Add" đang làm việc, mặc dù tôi không chắc chắn như thế nào. Từ những gì tôi có thể thu thập "Thêm" là nhận được một con trỏ đến tiêu đề slice (3 mục "struct"). Từ những gì tôi đã đọc, chiều dài và dung lượng của một slice không được truyền cho các phương thức (khi truyền theo giá trị), vì vậy có lẽ việc truyền con trỏ tới slice cho phép phương thức xem và sử dụng độ dài và dung lượng. để "nối thêm". Nếu điều này là đúng, thì tại sao cùng một mẫu không hoạt động trong "Xóa"?
Cảm ơn rất nhiều vì thông tin chi tiết và trợ giúp của mọi người!
package main
import (
"fmt"
)
type myStruct struct {
a int
}
type mySlice []*myStruct
func (slc *mySlice) Add(str *myStruct) {
*slc = append(*slc, str)
}
//does not compile with reason: cannot slice slc (type *mySlice)
//func (slc *mySlice) Remove1(item int) {
// *slc = append(*slc[:item], *slc[item+1:]...)
//}
func (slc mySlice) Remove(item int) {
slc = append(slc[:item], slc[item+1:]...)
fmt.Printf("Inside Remove = %s\n", slc)
}
func main() {
ms := make(mySlice, 0)
ms.Add(&myStruct{0})
ms.Add(&myStruct{1})
ms.Add(&myStruct{2})
fmt.Printf("Before Remove: Len=%d, Cap=%d, Data=%s\n", len(ms), cap(ms), ms)
ms.Remove(1) //remove element 1 (which also has a value of 1)
fmt.Printf("After Remove: Len=%d, Cap=%d, Data=%s\n", len(ms), cap(ms), ms)
}
và kết quả ...
Before Remove: Len=3, Cap=4, Data=[%!s(*main.myStruct=&{0}) %!s(*main.myStruct=&{1}) %!s(*main.myStruct=&{2})]
Inside Remove = [%!s(*main.myStruct=&{0}) %!s(*main.myStruct=&{2})]
After Remove: Len=3, Cap=4, Data=[%!s(*main.myStruct=&{0}) %!s(*main.myStruct=&{2}) %!s(*main.myStruct=&{2})]
Cảm ơn rất nhiều vì trả lời nhanh chóng của bạn Stephen! Vì vậy, chỉ cần làm rõ, khi truyền các slice tới các hàm/phương thức, thứ duy nhất được truyền qua là định nghĩa struct 3-lát của slice (không bao giờ là mảng cơ bản). Khi đi qua giá trị tôi đang đi qua một COPY của định nghĩa slice và khi đi qua sở thích tôi đang đi qua một con trỏ đến định nghĩa slice? Cảm ơn một lần nữa! – user2736464
Chính xác. Khi bạn chuyển một giá trị, bạn sẽ nhận được một bản sao của len, nắp và một con trỏ tới mảng sao lưu. Khi bạn vượt qua một con trỏ đến slice, bạn có thể sửa đổi len và nắp của bản gốc. –