2016-03-26 21 views
1

Dizeye dayalı bir işlev belirtmek istiyorum. Bir haritadan ipler alıyorum, aşağıdaki örnekte bunlar, haritayı birleştirirken function'daki değerlerdir. Örneğin, function == "networkInfo" dize değeri olduğunda, bu değeri gerçek fonksiyonların adı olarak "tedavi etmek" istiyorum. Açıklamak zor ama sanırım siz ne demek istediğimi anlayacaksınız.Dize değerini işlev çağrısına dönüştürme

Amacım, anahtar deyimini kaldırmak ve ağ iletişiminin function dizesinden ayıklanan işlev adı olduğu c.AddFunc(spec, func() { networkInfo() }) numaralı telefonu aramaktır. Bunun mümkün olduğunu biliyorum, ama ben :(Yardım takdir bilmiyorum

// ScheduleCronjobs starts the scheduler 
func ScheduleCronjobs() { 

tasks := props.P.GetStringMapString("tasks") 
log.Infof("number of tasks: %d", len(tasks)) 

if len(tasks) != 0 { 
    c := cron.New() 

    // for each task, initialize 
    for function, spec := range tasks { 
     switch function { 
     case "networkInfo": 
      c.AddFunc(spec, func() { networkInfo() }) 
     case "bla": 
      c.AddFunc(spec, func() { bla() }) 
     default: 
      log.Errorf("unknown task: %q", function) 
     } 
    } 
    c.Start() 
} 

// after initialization, send out confirmation message 
slack.SendMessage("tasks initialized", props.P.GetString("channel")) 
} 
+0

Tüm funcs'lerin aynı imzanın var olduğunu mu sanırım? Yani func() –

+0

Ayrıca, tüm funcs aynı pakette yaşıyor mu? –

+0

Evet, tüm işlevler (tüm "görevler") aynı imzana sahip. Ve tüm işlevler aynı pakette yaşıyor. –

cevap

3

Neden bir şey gibi:.!

taskDefs := map[string]func(){ 
    "networkInfo": networkInfo, 
    "bla": bla, 
} 

for function, spec := range tasks { 
    if fn, ok := taskDefs[function]; ok { 
    c.AddFunc(spec, func() { fn() }) // not sure if you need the enclosing func 
    } else { 
    log.Errorf("unknown task: %q", function) 
    } 
} 

sonra sizi sizin funcs imzaları değişen gerekiyorsa Gerçekten de yansımaya ihtiyacım var, ama eğer funkların tipleri aynıysa, o zaman bu harita yaklaşımını kullanmak yansıma yükü olmaksızın daha basit bir çözüm olabilir:

Fonksiyonları bulmayı bulmamın tek yolu Paket içindeki isim, kaynak dosyaları ayrıştırmaktır. This repo, func'leri bulma ve bunları anahtar olarak isimle bir haritaya saklama örneğidir.

Git bağlacı, ses çıkarılmamış funcs'ları sessizce bırakır; böylece, func'a başvurmanızın tek yolu yansıtma yoluyla yansırsa bozulur. Bu yüzden önerdiğim harita yaklaşımı daha üstündür; linker, func'in kullanıldığını bilir.

+0

Yanıtlarınız için teşekkürler, gerçekten bana çok yardımcı oluyorlar. Önerinizde, tüm "görevlerin" tanımlanması gereken bir "taskDefs" haritası [string] func() görüyorum. Bu bölümü atlamak mümkün değil mi? Bu sayede işlev ismini bir yapılandırma dosyasına koyarak ve görevlerimdeki "taskDefs" öğesine bir şey eklemeden işlevini uygulayarak görevleri ekleyebilirim. –

+1

@RogierLommers İstediğiniz şeyi anlıyorum; isim ve işlev arasındaki açık eşleşmeyi önlemek için. Bununla ilgili iki sorun var: 1) Yansıtmayla bunu yapmanın bir yolunu görmüyorum, aksi takdirde çalışma zamanındaki go ayrıştırıcı ile kaynağı dinamik olarak okumadıysanız, sonuçta aynı şeyi yapmak için daha yoğun bir yaklaşım gibi görünüyor (harita) adının çalışması). 2) Git linker, ilgisiz fonksiyonları bırakacaktır, bu yüzden, işlevin işe yaramayacağı başka bir yerde referans verilmemesi durumunda, son ikilide bile olmayacağının bir riski vardır. –