Во-первых, для того, что вы пытаетесь сделать, вы должны использовать fmt.Printf()
вместо fmt.Println()
, поскольку только первое ожидает и использует строку формата.
В дальнейшем это не поддерживается по умолчанию, потому что цитирование из Spec: Вызовы:
Как особый случай, если возвращаются значения функции или метода g
равны по числу и индивидуально присваиваются параметрам другой функции или метода f
, тогда вызов f(g(parameters_of_g))
вызовет f
после привязки возвращаемых значений g
к параметрам f
по порядку. Вызов f
не должен содержать никаких параметров, кроме вызова g
, а g
должен иметь хотя бы одно возвращаемое значение. Если f
имеет конечный параметр ...
, онприсваиваются возвращаемые значения g
, которые остаются после назначения обычных параметров.
И fmt.Printf()
имеет подпись:
func Printf(format string, a ...interface{}) (n int, err error)
Вы не можете передавать другие параметры вfmt.Printf()
помимо вызова функции (возвращаемые значения вызова).
Обратите внимание, что подпись fmt.Println()
:
func Println(a ...interface{}) (n int, err error)
Это означает, что fmt.Println(temp())
работает, иТо же самое относится и к любым другим функциям, которые имеют хотя бы одно возвращаемое значение, поскольку это позволяет последнее предложение части в кавычках ( "Если f
имеет конечный параметр ...
, ему присваиваются возвращаемые значения g
которые остаются после назначения обычных параметров. ")
Но с небольшой хитростью мы можем достичь того, что вы хотите, с помощью fmt.Printf()
.
Примечаниечто если temp()
вернет значение типа []interface{}
, мы могли бы использовать ...
чтобы передать его как значение некоторого параметра переменной.
Это означает, что работает:
func main() {
fmt.Printf("1: %v, 2: %v\n", temp()...)
}
func temp() []interface{} { return []interface{}{1, 2} }
И он правильно печатает (попробуйте на Go Playground ):
1: 1, 2: 2
Итак, нам просто нужна служебная функция, которая упаковывает возвращаемые значения любой функции в []interface{}
, и поэтому мы можем использовать ее для передачи fmt.Printf()
.
И это очень просто:
func wrap(vs ...interface{}) []interface{} {
return vs
}
Как описано выше (с fmt.Println()
), мы можем передать возвращаемые значения любой функции, которая имеет по крайней мере 1 возвращаемое значение, wrap()
как значения еевходные параметры.
Теперь с помощью этой функции wrap()
см. следующий пример:
func main() {
fmt.Printf("1: %v\n", wrap(oneInt())...)
fmt.Printf("1: %v, 2: %v\n", wrap(twoInts())...)
fmt.Printf("1: %v, 2: %v, 3: %v\n", wrap(threeStrings())...)
}
func oneInt() int { return 1 }
func twoInts() (int, int) { return 1, 2 }
func threeStrings() (string, string, string) { return "1", "2", "3" }
Это работает и выводит данные (попробуйте на Go Playground ):
1: 1
1: 1, 2: 2
1: 1, 2: 2, 3: 3
Подробнее об этой теме см. Соответствующий вопрос:
Несколько значений в контексте с одним значением
Возвращает карту как 'ok' в Голанге для нормальных функций