lua 学习笔记7

lua 学习笔记7

/*******************/
  自定义数据文件
/*******************/
常常有大量数据需要引入,有没有更加人性化的输入方式呢?
在lua中,可以采用下面的方式:
定义数据文件data:
其格式如:
    Entry{"Donald E. Knuth",
          "Literate Programming",
          "CSLI",
          1992}
   
    Entry{"Jon Bentley",
          "More Programming Pearls",
          "Addison-Wesley",
          1990}
ps:Entry{…} 和Entry({…})是一样的意思,调用Entry函数。
然后在需要引用数据的地方,采用dofile("data")来导入数据。
处理时,要预先加入function Entry(b)来对引用的数据进行处理
例如,我们需要统计上面的数据中第一项的个数
    local count = 0
    function Entry (b) count = count + 1 end
    dofile("data")
    print("number of entries: " .. count)
/*******************/
  保存表格的内容
/*******************/
有时候需要把lua中的表格内容保存到文件中,并且保存的格式是可以直接读取的语法形式,在表格中的引用也要相应的保存起来.
  
  function basicSerialize (o)
      if type(o) == "number" then
        return tostring(o)
      else   — assume it is a string
        return string.format("%q", o)
      end
    end
  function save (name, value, saved)
      saved = saved or {}       — initial value
      io.write(name, " = ")
      if type(value) == "number" or type(value) == "string" then
        io.write(basicSerialize(value), "n")
      elseif type(value) == "table" then
        if saved[value] then    — value already saved?
          io.write(saved[value], "n")  — use its previous name
        else
          saved[value] = name   — save name for next time
          io.write("{}n")     — create a new table
          for k,v in pairs(value) do      — save its fields
            local fieldname = string.format("%s[%s]", name,
                                            basicSerialize(k))
            save(fieldname, v, saved)
          end
        end
      else
        error("cannot save a " .. type(value))
      end
    end
例如:
   a = {x=1, y=2; {3,4,5}}
    a[2] = a    — cycle
    a.z = a[1]  — shared sub-table
执行save(‘a’, a) will save it as follows:
    a = {}
    a[1] = {}
    a[1][1] = 3
    a[1][2] = 4
    a[1][3] = 5
   
    a[2] = a
    a["y"] = 2
    a["x"] = 1
    a["z"] = a[1]
/*****************/
   Metatables
/*****************/
定义方法如:
    t1 = {}
    setmetatable(t, t1)
获取方法:
    assert(getmetatable(t) == t1)
Any table can be the metatable of any other table; a group of related tables may share a common metatable (which describes their common behavior); a table can be its own metatable (so that it describes its own individual behavior). Any configuration is valid.
/***************************/
  Metetables用于重载运算符
/***************************/
Set.mt = {}    — metatable for sets
Set.mt.__add = Set.union
Set.mt.__mul = Set.intersection
function Set.union (a,b)

end
   
function Set.intersection (a,b)

end
然后就定义了+ 和 * 两种运算符(效果: s3 = s1 + s2,(s1 + s2) * s1)
这些定义的方法称为metamethods
/***********************/
      metamethods
/***********************/
metamethods 有 __add(add),__mul(multiple),__eq (equality), __lt (less than), and __le (less or equal).
There are no separate metamethods for the other three relational operators, as Lua translates a ~= b to not (a == b), a > b to b < a, and a >= b to b <= a.
/*****************************/
   防止metatable被修改的方法
/*****************************/
The setmetatable/getmetatable functions use a metafield also, in this case to protect metatables. Suppose you want to protect your sets, so that users can neither see nor change their metatables. If you set a __metatable field in the metatable, getmetatable will return the value of this field, whereas setmetatable will raise an error:
    Set.mt.__metatable = "not your business"
   
    s1 = Set.new{}
    print(getmetatable(s1))     –> not your business
    setmetatable(s1, {})
      stdin:1: cannot change protected metatable
/*************************/
  The __index Metamethod
/*************************/
当我们访问table的不存在的域时(an absent field in a table),系统会返回一个nil,事实上,系统是通过查询__index这个Metamethod方法来获得值的,因为一开始这个方法没有定义,所以会返回nil.
__index这个方法的用法:
    — create a namespace
    Window = {}
    — create the prototype with default values
    Window.prototype = {x=0, y=0, width=100, height=100, }
    — create a metatable
    Window.mt = {}
    — declare the constructor function
    function Window.new (o)
      setmetatable(o, Window.mt)
      return o
    end
Now, we define the __index metamethod:
    Window.mt.__index = function (table, key)
      return Window.prototype[key]
    end
After that code, we create a new window and query it for an absent field:
    w = Window.new{x=10, y=20}
    print(w.width)    –> 100
另外还有更加简便的方法:
The use of the __index metamethod for inheritance is so common that Lua provides a shortcut. Despite the name, the __index metamethod does not need to be a function: It can be a table, instead. When it is a function, Lua calls it with the table and the absent key as its arguments. When it is a table, Lua redoes the access in that table. Therefore, in our previous example, we could declare __index simply as
    Window.mt.__index = Window.prototype
如果我们不需要系统返回__index的值时,可以采用:
When we want to access a table without invoking its __index metamethod, we use the rawget function. The call rawget(t,i) does a raw access to table t. Doing a raw access will not speed up your code (the overhead of a function call kills any gain you could have), but sometimes you need it, as we will see later.
/*****************************/
  The __newindex Metamethod
/*****************************/
The __newindex metamethod does for table updates what __index does for table accesses. When you assign a value to an absent index in a table, the interpreter looks for a __newindex metamethod: If there is one, the interpreter calls it instead of making the assignment. Like __index, if the metamethod is a table, the interpreter does the assignment in that table, instead of in the original one. Moreover, there is a raw function that allows you to bypass the metamethod: The call rawset(t, k, v) sets the value v in key k of table t without invoking any metamethod.
The combined use of __index and __newindex metamethods allows several powerful constructs in Lua, from read-only tables to tables with default values to inheritance for object-oriented programming. In the rest of this chapter we see some of these uses. Object-oriented programming has its own chapter.
/***********************************/
    利用表格的__index __newindex
/***********************************/
oth __index and __newindex are relevant only when the index does not exist in the table. The only way to catch all accesses to a table is to keep it empty. So, if we want to monitor all accesses to a table, we should create a proxy for the real table. This proxy is an empty table, with proper __index and __newindex metamethods, which track all accesses and redirect them to the original table. Suppose that t is the original table we want to track. We can write something like this:
    t = {}   — original table (created somewhere)
   
    — keep a private access to original table
    local _t = t
   
    — create proxy
    t = {}
   
    — create metatable
    local mt = {
      __index = function (t,k)
        print("*access to element " .. tostring(k))
        return _t[k]   — access the original table
      end,
   
      __newindex = function (t,k,v)
        print("*update of element " .. tostring(k) ..
                             " to " .. tostring(v))
        _t[k] = v   — update original table
      end
    }
    setmetatable(t, mt)
This code tracks every access to t:
    > t[2] = ‘hello’
    *update of element 2 to hello
    > print(t[2])
    *access to element 2
    hello
(Notice that, unfortunately, this scheme does not allow us to traverse tables. The pairs function will operate on the proxy, not on the original table.)
/********************************/
   __index __newindex的多代理
/********************************/
If we want to monitor several tables, we do not need a different metatable for each one. Instead, we can somehow associate each proxy to its original table and share a common metatable for all proxies. A simple way to associate proxies to tables is to keep the original table in a proxy’s field, as long as we can be sure that this field will not be used for other means. A simple way to ensure that is to create a private key that nobody else can access. Putting these ideas together results in the following code:
    — create private index
    local index = {}
   
    — create metatable
    local mt = {
      __index = function (t,k)
        print("*access to element " .. tostring(k))
        return t[index][k]   — access the original table
      end,
   
      __newindex = function (t,k,v)
        print("*update of element " .. tostring(k) ..
                             " to " .. tostring(v))
        t[index][k] = v   — update original table
      end
    }
   
    function track (t)
      local proxy = {}
      proxy[index] = t
      setmetatable(proxy, mt)
      return proxy
    end
Now, whenever we want to monitor a table t, all we have to do is t = track(t).

2 thoughts on “lua 学习笔记7

  1. Hi,Do you need advertising displays, screen advertisings, digital sign, digital signages and LCDs? Please go Here:www.amberdigital.com.hk(Amberdigital).we have explored and developed the international market with professionalism. We have built a widespread marketing network, and set up a capable management team dedicated to provide beyond-expectation services to our customers.
    amberdigital Contact Us
    E-mail:sstar@netvigator.com
    website:www.amberdigital.com.hk
    alibaba:amberdigital.en.alibaba.com[i

  2. wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling -229064276978696

Leave a Reply

Your email address will not be published. Required fields are marked *