Please answer these questions before submitting your issue. Thanks!
go version)?go version go1.8.3 windows/amd64
go env)?Don't mind.
type S string
func fn(s ...S) {}
func TestFn(t *testing.T) {
fn(S(""), S(""))
fn("", "")
fn(S(""), "")
fn([]S{S(""), S("")}...)
fn([]string{"", ""}...)
}
Everything should works well.
I got an error: cannot use []string literal (type []string) as type []S in argument to fn

Is it a reasonable behaviour? That's my derivation:
fn(T, T, T, ...) == fn(t, t, t, ...)
[]T... => T, T, T, ...
fn([]T...) => fn(T, T, T, ...) => fn(t, t, t, ...) => Accept!
The way it works is useful: https://play.golang.org/p/QCZDykSKAY.
@cznic r u kid me? u think I don't know how to use it?
u think I don't know how to use it?
The title says "_behavior of ... operator looks strange!._". I've just presented an example in which I tried to show why it is important for ... to work the way it does.
Of course I know what to do, I don't need someone to teach me how to it work. What I need is, why it works like those, how it be designed to this style, and could it work better use different way.
S and string are not the same type. You can not use fn(string("")) either.
You'll have to cast your S to string manually.
@zegl try this please
package main
type S []string
func fn(s ...S) {}
func main() {
fn(S{""}, S{""})
fn([]string{""}, []string{""})
fn(S{""}, []string(S{""}))
fn([]S{S{""}, S{""}}...)
// fn([][]string{[]string{""}, []string{""}}...)
}
The documentation supports this behavior.
https://golang.org/ref/spec#Passing_arguments_to_..._parameters
If the final argument is assignable to a slice type []T, it may be passed unchanged as the value for a ...T parameter if the argument is followed by .... In this case no new slice is created.
Values of type [][]string is not assignable to the type []S, so it fails.
Given func fn(args ...string) and list := []string{"", ""},
fn(list...) is not identical to fn(list[0], list[1]).
fn(list...) meansargs = list while fn(list[0], list[1]) means
args = make([]string, 2); args[0] = list[0]; args[1] = list[1].
@zhengxiaoyao0716
Please do not use rhetorical question. It's unfriendly.
Closing because this is working as documented.
If you want to discuss why it works this way, please use the golang-nuts mailing list. Thanks.
Please be polite to people who are just trying to help. Thanks.
@crvv well, thank for your remind, I don't known rhetorical question is unfriendly before.
In Chinese,

is normal tone.
And from Chinese rhetorical question translate to English by Google:

u see, there are no different...
@ianlancetaylor ok, That's really my fault.
But i don't think this is working as documented, at least not in https://golang.org/ref/spec#Passing_arguments_to_..._parameters
The key of this problem is, I think mistack that a string value can assigned to S directly.
type S string
func TestS(t *testing.T) {
var s S
s = ""
var str = ""
// I think mistack that a string value can assigned to S directly.
// s = str
fmt.Println(s)
}
I'm not a new learner, but i always forgot to use s = S(str) instead of s = str, so today it puzzled me.
@zegl But there are still some problem, i really can not use fn(string("")), but in another case tha type S []string, why could i use fn([]string(S{""}))?
The language spec, in the section you cite, says that given a function f(...S) and a call f(s...), that the slice s must be assignable to []S. In your example s is []string, and []string is not assignable to []S, so the code does not compile. So I believe I am correct in saying that this is working as documented.
@ianlancetaylor yes, i known that the slice s must be assignable to []S at the beginning, that's a grammatical mistake. i'm ask for help that why this happend, and I'm glad I got it. Thank you all and please forgive my willfulness.
Most helpful comment
The documentation supports this behavior.
https://golang.org/ref/spec#Passing_arguments_to_..._parameters
Values of type
[][]stringis not assignable to the type[]S, so it fails.Given
func fn(args ...string)andlist := []string{"", ""},fn(list...)is not identical tofn(list[0], list[1]).fn(list...)meansargs = listwhilefn(list[0], list[1])meansargs = make([]string, 2); args[0] = list[0]; args[1] = list[1].@zhengxiaoyao0716
Please do not use rhetorical question. It's unfriendly.