2014-07-07 18 views
8

Yeni bir kullanıcıyım ve bu sorunla neredeyse tüm gün mücadele ediyordum. olarak bu işleyici işlevi geçmekarabirimi {} işlev türüne dönüştürebilme

typedHandler = func() { 
    fmt.Println("in a handler!\n") 
} 

Ama neye yapmam gereken: Ben typedObject böyle değişkene bir fonksiyon atayabilirsiniz

type HandlerType func() 
var object interface{} 
var typedObject HandlerType 

:

düşünüldüğünde de bunlar var Bir arabirim {} değişkeni ve sonra bir şekilde daha sonra arayabileceğim HandlerType'a dönüştürüyorum.

Denedim ama

interface conversion: interface is func(), not main.HandlerType

Temelde ben kayıt olmadan önce ek tip dönüşümü olmaksızın farklı imzalara sahip fonksiyonlarını kaydetmeniz gerekir: içinde

typedHandler = object.(HandlerType) 

sonuçları: o hata verir. Bunun yerine bunu yapmanın:

registerHandler(HandlerTypeString(func() string { ... })) 
registerHandler(HandlerTypeVoid(func() { ... })) 

böyle işleyicileri kaydetmek istediğiniz:

registerHandler(func() string { ... }) 
registerHandler(func() { ... }) 

.. ve ben daha sonra bir işleyici çağrısının zaman

de yansımasını dahil etmek istemiyoruz

Mümkün mü?

Düzenleme: Ben arayüzünde {} gibi bazı keyfi fonksiyonunu geçmek ve sonra bir şekilde HandlerType veya başka önceden tanımlanmış dönüştürmek için bir yolu yoktur anladığım kadarıyla http://play.golang.org/p/UlwqkHjt_P

: Ben bir oyun alanı oluşturduk işlev türü bu yüzden yansıma kullanmadan arayabilir miyim?

Edit2

: Bu çözüm geldi ettik: http://play.golang.org/p/4gUxsgmiPf

bu kodla çalışma zamanı sırasında herhangi bir performans ceza yoktur olmamalıdır. Ama birisi arabirimi {} arabirimi olmadan bu işlevselliği gerçekleştirmenin başka bir yolunu düşünebilir mi?

+1

göster tam kod nasıl yapılacağına ilişkin orada bir örnek vardır reflect.MakeFunc ile artık bunu yapabilirsiniz. 'typedHandler = nesne. (HandlerType)' ** ** nesne ('' interface {} 'türünde) gerçekten' HandlerType' nesnesini içeriyorsa çalışacaktır. Oyun alanında oynanabilir kodu göster. – Volker

+1

Bir tane daha: Eğer Yeni Başlayan iseniz, arayüzden {} 'kaçınmalısınız. Finde başka bir yol, yazar uygun Go kodu. 'Interface {} 'adlı sihirbaz, başka bir dilden kod çevirisi gibi kokuyor. – Volker

+0

Ben neyi başarmak istediğimi açık yaptığımı düşündüğüm bir oyun alanı ekledim :) – user3668351

cevap

4

Sen, farklı bir tip, sadece kullanabilirsiniz olabilir object.(func()), object.(func() string), vb söz konusu küçük bir dizi yanlış anlamanın vardır

func main() { 
    type HandlerType func() 
    var object interface{} = func() { 
     fmt.Println("eureka!") 
    } 
    if f, ok := object.(func()); ok { 
     HandlerType(f)() 
    } 
} 
+0

Teşekkür ederim! Şimdi istediğimi nasıl uygulayacağım. http://play.golang.org/p/4gUxsgmiPf – user3668351

+0

Aslında bu belirli model için muhtemelen @Elwinar'ın önerdiği gibi bir arayüz kullanmanız daha iyi olacaktır. – OneOfOne

6

:

  1. Tipi iddialar türlerini yayınlamak için kullanılmaz. Tek yaptığı, bir değişkenin verilen türde olup olmadığını kontrol etmektir ve değişkeni bu temel tür olarak döndürmektir. Bu işlem, durumunuzda bir hata döndürür; bu, func()'un HandlerFunc türünde olmaması durumunda normaldir.

  2. interface{} kabul eden bir işlevde bir değişken parametre olarak geçmek için hiçbir şey yapmanıza gerek yoktur. Her tür, boş arabirimi örtük olarak uygular.

  3. bir func()HandlerTypetype HandlerType func() tarafından tanımlanmış olsa bile, bir HandlerType değildir. Tanımın bununla hiçbir ilgisi yoktur.

Yapmak istediğiniz şey mümkün değil. Ben yansımayla ilgili bir uzman değilim, ama bu düşüncenin de senin problemini çözebileceğini sanmıyorum.

Bu, kayıt yönteminizin tüm kayıtlı nesnelerin gerçekleştirmesi gereken bir arabirim tanımlaması ve bu arabirimi parametre türü olarak kullanması gerektiğini söyledi. Örnek için database/sql paket Register yöntemine bakın.