Розпакуйте масив як аргументи


104

Отже, в Python та Ruby існує оператор splat (*) для розпакування масиву як аргументів. У Javascript є функція .apply (). Чи є спосіб розпакувати масив / зріз як аргументи функції в Go? Будь-які ресурси для цього також були б чудовими!

Щось подібне до цього:

func my_func(a, b int) (int) {
    return a + b
}

func main() {
    arr := []int{2,4}
    sum := my_func(arr)
}

Я перепрошую, якщо роблю синтаксичні помилки. Я новачок у Go.


4
Перш за все, arrце не масив. Це скибочка .
newacct

Відповіді:


160

Ви можете використовувати синтаксис vararg, подібний до C:

package main
import "fmt"

func my_func( args ...int) int {
   sum := 0
   for _,v := range args {
      sum = sum + v
   }

   return sum;
}

func main() {
    arr := []int{2,4}
    sum := my_func(arr...)
    fmt.Println("Sum is ", sum)
}

Тепер ви можете підсумувати скільки завгодно речей. Зверніть увагу на важливе ...після того, як ви викликаєте my_funcфункцію.

Приклад запуску: http://ideone.com/8htWfx


8

Або ваша функція - це varargs, в яких ви можете використовувати фрагмент із ...позначеннями, як показує Хантер Макміллен, або ваша функція має фіксовану кількість аргументів, і ви можете розпакувати їх під час написання коду.

Якщо ви дійсно хочете зробити це динамічно з функцією фіксованої кількості аргументів, ви можете використовувати відображення:

package main
import "fmt"
import "reflect"

func my_func(a, b int) (int) {
    return a + b
}

func main() {
    arr := []int{2,4}
    var args []reflect.Value
    for _, x := range arr {
        args = append(args, reflect.ValueOf(x))
    }
    fun := reflect.ValueOf(my_func)
    result := fun.Call(args)
    sum := result[0].Interface().(int)
    fmt.Println("Sum is ", sum)
}

Мені цікаво спостерігати, як підходять ці орієнтири проти вараргів. Я вважаю, що це буде працювати менш ефективно, але мені доведеться розглянути це.
Hunter McMillen

@HunterMcMillen чи отримали Ви якесь уявлення про порівняння продуктивності?
AkiRoss

Можливо, @AkiRoss, але це було так давно, що я забув результати: |
Hunter McMillen

хай добре, не біда: гадаю, все одно це повільніше, можливо, я сам проведу деякі тести. Thanx
AkiRoss

0

https://play.golang.org/p/2nN6kjHXIsd

У мене була причина розпакувати кілька варів із рядка map [рядок] з одинарними лапками навколо деяких з них, а також без. Ось логіка для цього, і посилання на відтворення зверху має повний робочий фрагмент.

func unpack(a map[string]string) string {

var stmt, val string
var x, y []string
for k, v := range a {
    x = append(x, k)
    y = append(y, "'"+v+"'")
}

stmt = "INSERT INTO tdo.rca_trans_status (" + strings.Join(x, ", ")
val = ") VALUES (" + strings.Join(y, ",") + ");"

return stmt + val}

Що подається чисто для запиту mssql як:

INSERT INTO tdo.rca_trans_status (rca_json_body, original_org, md5sum, updated, rca_key) VALUES ('blob','EG','2343453463','2009-11-10 23:00:00','prb-180');

-16

Ні, прямої підтримки цього в мові немає. Python і Ruby, а також Javascript, про який ви згадуєте; - це всі мови динаміки / сценаріїв. Go - це набагато ближче, наприклад, C, ніж будь-яка динамічна мова. Функціональність "застосувати" зручна для динамічних мов, але мало використовується для статичних мов, таких як C або Go,


@ user7610 ви помиляєтесь. Ви маєте на увазі інший випадок, ніж питання. В оригінальному запитанні немає варіативного параметра в оголошенні функції.
user2846569

Так, я, мабуть, був. Те, що робить Python / Ruby, можна розглядати як синтаксичний цукор для відбивального дзвінка, який підтримує Go ...
user7610
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.