2015-01-13 31 views
6

Mam następujący kod:Czy istnieje jakaś sztuczka do używania makr w tym samym pliku, który są zdefiniowane?

object Macros { 

    import scala.language.experimental.macros 
    import scala.reflect.macros.blackbox 

    def hello(): Unit = macro hello_impl 

    def hello_impl(c: blackbox.Context)(): c.Expr[Unit] = { 
    import c.universe._ 
    reify { 
     println("Hello World!") 
    } 
    } 
} 


object Main { 

    def main(args: Array[String]): Unit = { 
    Macros.hello() 
    } 

} 

To wyrzuca następujący błąd kompilacji:

Error:(21, 17) macro implementation not found: hello 
(the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them) 
    Macros.hello() 
       ^

Moje pytanie brzmi: czy jest jakiś sposób, aby „oszukać” kompilator w celu wykorzystania rozszerzeń makr w ten sam plik, który są zdefiniowane? Moja motywacja jest następująca: lubię kodować w Scali, a ostatnio zgłaszałem pewne problemy w sędziach internetowych Codeforces, a niektóre konstrukcje Scali okazały się bardzo powolne. Tak więc chcę utworzyć pewne rozszerzenia makr, aby szybko wykonać te konstrukcje. Ale nie mogę przesłać więcej niż jednego pliku.

Dzięki!

+0

Nie sądzę, że to możliwe. Nie jestem pewien, ale brzmi to dziwnie, aby utworzyć makro (które musi zostać skompilowane), a następnie użyć go, gdy nie zostanie skompilowane. Jednak możesz je zdefiniować w różnych plikach? Nie jestem tego pewien. Inną rzeczą przy wykonywaniu CF z Scala jest to, że powinieneś unikać takich rzeczy jak filtry, flatMap itp., Ponieważ są one wolne w większych kolekcjach. Trzymaj się tablic i powinieneś osiągnąć wydajność zbliżoną do java w większych kolekcjach. –

+0

Zgadzam się z tobą na temat zasad "trzymaj do tablic". Ale okazuje się, że do zrozumienia są niesamowicie powolne (prawdopodobnie dlatego, że są przekształcane w sekwencję map-flatMap-filter) nawet w przypadku tablic i jest to wielki ból, który można wykorzystać podczas iteracji. Na przykład, lepiej pisać w Javie niż pisać ten http://codeforces.com/contest/166/submission/8828271 tylko dlatego, że for-comprehensions powoduje to TLE. – ale64bit

+0

Jedna rzecz, którą widzę za pomocą tego kodu, to że Skaner działa bardzo wolno. Zamiast tego napisz własną klasę używając danych wejściowych. Sprawdź to: https://kattis.csc.kth.se/doc/src/Kattio.java (niestandardowy czytnik silnika mojej szkoły) –

Odpowiedz

5

W chwili obecnej nie jest to możliwe w wersjach produkcyjnych Scala 2.10 i 2.11. Możemy to osiągnąć za pomocą scala.meta, ale to dobrze w przyszłości.