In fact, the use of macros is not difficult, the API has helped us do everything, we just focus on how to use the Get macro parameters and the return value of the macro
An example:
Import scala.reflect.macros.Context
Import scala.collection.mutable.{ Listbuffer, Stack}
object Qstringimpl {
def qmap (P:char = int,elem:string): INT = Macro Qstringimpl.map_impl
def Map_impl (c:context) (P:c.expr[char = int],elem:c.expr[string]): c.expr[int] = {
import c.universe._< C5/>//splice can only be used in reify, materialized, function and reify opposite
reify {elem.splice.map (p.splice). Sum}}}
Import Scala.language.experimental.macros
Object DemoTest2 extends app{
import qstringimpl._
val result = Qmap (_.toint + 1, "111111")
println (result)
}
There are official examples in Scala, but they are written by someone else and they don't feel well written! As I said above, no matter how the Scala macros are officially implemented, for programmers only need to know how to get parameters and return parameters, this is the official Doc tutorial
Http://docs.scala-lang.org/overviews/macros/overview.html
Google once, to find a better example, it is easy to understand that the use of macro to pay attention to the global variable dependency
Link http://www.warski.org/blog/2012/12/starting-with-scala-macros-a-short-tutorial/
Put it on the way.
Starting with Scala macros:a short tutorial by Adam Warski 2 December, Comments
Using some time during the weekend, I decided to finally explore one of the new features in the coming Scala 2.10, macros. Macros was also written in Scala so in essence a macro was a piece of Scala code, executed at Compile-time, which Manipulat Es and modifies the AST of a Scala program.
To does something useful, I wanted to implement a simple macro for debugging; I suppose I ' m not alone in using println-debugging, that's debugging by inserting statements like:
1
|
println ("after register; user = "+ user +", UserCount = "+ UserCount) |
Running a test, and checking what's the output is. Writing the variable name before the variable is tedious, so I wanted to write a macro which would does that for me; That is:
1
|
Debug ("After register", user, UserCount) |
Should has the same effect as the first snippet (it should generate code similar to the one above).
Let's see step-by-step what to implement such a macro. There ' s a good Getting Started guide on the Scala macros page, which I used. All code explained below are available on GitHub, in the Scala-macro-debug project. 1. PROJECT SETUP
To experiment comfortably we'll need to setup a simple project first. We'll need at least-subprojects:one for macros, and one for testing the macros. That's because the macros must be compiled separately and before and code that uses them (as they influence the Compilati On process).
Moreover, the macro subproject needs to has a dependency on scala-compiler, to is able to access the reflection and AST C Lasses.
A Simple SBT Build file could look like This:Build.scala. 2. HELLO world!
"Hello world!" is always a great starting point. So my first step is to write a macro, which would expand hello () to println ("Hello world!") at Compile-time.
In the macros subproject, we had to create a new object, which defines hello () and the macro:
1 2 3 4 5 6 7 8 9 ten page |
package com. Softwaremill.debug Import language.experimental.macros Import reflect.macros.Context Object
Debugmacros {def hello (): UNIT = macro Hello_impl def hello_impl (C:context) (): C.expr[unit] = {//TODO }
} |
There is a couple of important things Here:we has to import Language.experimental.macros, to enable the macros feature In the given source file. Otherwise we ' ll get compilation errors reminding us about the import. The definition of Hello () uses the macro keyword, followed by a method which implements the macro the macro implementation has both parameter lists:the first is the context (what can think about it as a compilation context), the second mirrors T He parameter list of our Method–here it ' s empty. Finally, the return type must also match–however in the method we had a return type unit, in the macro we return an EXP Ression (which wraps a piece of an AST) of type unit.
Now to the implementation, which are pretty short: