2015-01-13 2 views
6

У меня есть следующий код:Есть ли какой-либо трюк для использования макросов в том же файле, который они определены?

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() 
    } 

} 

Он выдает следующее сообщение об ошибке компиляции:

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() 
       ^

Мой вопрос: есть ли способ, чтобы «обмануть» компилятор, чтобы использовать макро-разложения в тот же файл, который они определены? Моя мотивация такова: мне нравится код в Scala, и в последнее время я задавал некоторые проблемы в онлайн-судье Codeforces, а некоторые конструкции Scala оказались очень медленными. Итак, я хочу создать некоторые макрорасширения, чтобы быстро выполнить эти построения. Но я не могу представить более одного файла.

Спасибо!

+0

Я не думаю, что это возможно. Не уверен, но странно создавать макрос (который нужно скомпилировать), а затем использовать его, когда он не скомпилирован. Однако вы можете определить их в разных файлах? Не уверен, хотя. Еще одна вещь, когда вы делаете CF с Scala, заключается в том, что вам следует избегать таких вещей, как фильтры, flatMap и т. Д., Поскольку они медленны в больших коллекциях. Придерживайтесь массивов, и вы должны получить почти-java-производительность в больших коллекциях. –

+0

Я согласен с вами в отношении политики «stick-to-arrays». Но оказывается, что for-comprehensions невероятно медленны (вероятно, потому, что они преобразуются в последовательность map-flatMap-filter) даже для массивов, и очень больно использовать, пока все вокруг повторяются. Например, предпочтительнее писать на Java, чем писать этот http://codeforces.com/contest/166/submission/8828271 только потому, что для понимания это вызывает TLE. – ale64bit

+0

Ну, одна вещь, которую я вижу с этим кодом, - это то, что сканер очень медленный. Вместо этого создайте собственный класс, используя входные потоки. Проверьте это: https://kattis.csc.kth.se/doc/src/Kattio.java (пользовательский читатель моей школы) –

ответ

5

На данный момент это невозможно в выпусках продукции Scala 2.10 и 2.11. Мы могли бы достичь этого с помощью scala.meta, но это хорошо в будущем.

 Смежные вопросы

  • Нет связанных вопросов^_^