Sự khác biệt giữa chuỗi [] và… chuỗi trong golang là gì?


85

Trong ngôn ngữ cờ vây,

[]string là một mảng chuỗi

và chúng tôi cũng sử dụng ...stringnhư một tham số.

Sự khác biệt là gì?

Định nghĩa hàm:

func f(args ...string) {}

Tôi có thể gọi chức năng này như dưới đây không?

args := []string{"a", "b"}

f(args)

Câu trả lời:


126

[]string là một mảng chuỗi

Về mặt kỹ thuật, nó là một lát cắt tham chiếu đến một mảng cơ bản

và chúng tôi cũng sử dụng ...stringnhư một tham số.

Sự khác biệt là gì?

Đối với cấu trúc, không có gì thực sự. Kiểu dữ liệu do cả hai cú pháp đều giống nhau.

Các ...cú pháp tham số làm cho một tham số variadic. Nó sẽ chấp nhận không hoặc nhiều stringđối số và tham chiếu chúng như một lát cắt.

Đối với việc gọi f, bạn có thể chuyển một đoạn chuỗi vào tham số variadic với cú pháp sau:

func f(args ...string) {
    fmt.Println(len(args))
}


args := []string{"a", "b"}

f(args...)

Cú pháp này có sẵn cho lát được xây dựng bằng cú pháp chữ hoặc lát đại diện cho tham số biến thể (vì thực sự không có sự khác biệt giữa chúng) .

http://play.golang.org/p/QWmzgIWpF8


10
[]stringlà một lát, không phải là một mảng. Sự khác biệt giữa mảng và lát là nhỏ nhưng quan trọng.
Stephen Weinberg

@StephenWeinberg: Vâng, câu trả lời "thực sự không có gì" của tôi cho câu trích dẫn "sự khác biệt là gì" đang trả lời câu hỏi được hỏi về sự khác biệt giữa phần được tạo bởi tham số hàm variadic và phần được tạo bằng []stringcú pháp. Tôi sẽ thêm nhiều câu trích dẫn vào câu trả lời của mình để làm cho nó rõ ràng hơn. :-)
I Hate Lazy

@IHateLazy Có cách nào để làm cho nội trang printlnhoạt động với dấu chấm lửng không? Ở đây bạn có thể tìm thấy các thí nghiệm của tôi. Nếu ai đó muốn một số chức năng in gỡ lỗi, hãy xem playgound của tôi.
vault

14

Cả hai đều tạo ra một mảng các chuỗi, nhưng sự khác biệt là ở cách nó được gọi.

func f(args ...string) {

}
// Would be called like this:

f("foo","bar","baz");

Điều này cho phép bạn chấp nhận một số lượng thay đổi các đối số (tất cả cùng một loại)

Một ví dụ tuyệt vời về điều này là fmt.Printvà những người bạn, có thể chấp nhận ít hoặc nhiều cuộc cung cấp tùy thích.


Tôi không phải là chuyên gia cờ vây, nhưng không phải một đối số đa dạng và đối số kia không phải là đối số mảng đơn lẻ và hai đối số này không khác biệt như trong các ngôn ngữ khác sao?
Lightness Races ở Orbit

1
@LightnessRacesinOrbit Yup. Nếu điều đó không rõ ràng thì xin lỗi vì sự nhầm lẫn. Dòng đầu tiên về cả việc tạo một mảng chỉ có nghĩa là đối số kết quả trong cả hai trường hợp là một mảng. Nó gần giống với def fn(*args)cấu tạo của python .
tylerl 16/10/12

Vì vậy, Go hiển thị các đối số khác nhau như một thể hiện của một kiểu mảng? Thật dễ chịu.
Các cuộc đua ánh sáng trong quỹ đạo vào

Trên thực tế, cả hai đều tạo ra một lát chuỗi, Không phải một mảng. Chúng là những thứ khác nhau trong golang.
PointerToConstantChar

Cả hai đều không tạo ra một "mảng" chuỗi, chúng tạo ra một "lát" chuỗi.
Inanc Gumus


1

Nó đơn giản hóa các tham số chức năng của bạn. Đây là một ví dụ ( https://play.golang.org/p/euMuy6IvaM ): Phương thức SampleEllipsis chấp nhận từ 0 đến nhiều tham số cùng kiểu nhưng trong phương thức SampleArray, bắt buộc phải khai báo args .

package main

import "fmt"

func SampleEllipsis(args ...string) {
    fmt.Printf("Sample ellipsis : %+v\n",args)
}


func SampleArray(args []string) {
    fmt.Println("Sample array ")
    SampleEllipsis(args...)
}

func main() {
    // Method one
    SampleEllipsis([]string{"A", "B", "C"}...)
    // Method two
    SampleEllipsis("A", "B", "C")
    // Method three
    SampleEllipsis()

    // Simple array
    SampleArray([]string{"A", "B", "C"})

    // Simple array
    SampleArray([]string{})

}

Lợi nhuận:

Sample ellipsis : [A B C]
Sample ellipsis : [A B C]
Sample ellipsis : []
Sample array 
Sample ellipsis : [A B C]
Sample array 
Sample ellipsis : []
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.