当前位置: 首页 > news >正文

想做个外贸网站免备案虚拟空间

想做个外贸网站,免备案虚拟空间,用mediawiki做的网站,网站描述修改迭代器和泛型for 迭代器和闭包 迭代器#xff08;iterator#xff09;是一种可以让我们遍历一个集合中所有元素的代码结构。在Lua语言中#xff0c;通常使用函数表示迭代器#xff1a;每一次调用函数时#xff0c;函数会返回集合中的“下一个”元素。 一个闭包就是一个…迭代器和泛型for 迭代器和闭包 迭代器iterator是一种可以让我们遍历一个集合中所有元素的代码结构。在Lua语言中通常使用函数表示迭代器每一次调用函数时函数会返回集合中的“下一个”元素。 一个闭包就是一个可以访问其自身的环境中一个或多个局部变量的函数。这些变量将连续调用过程中的值并将其保存在闭包中从而使得闭包能够记住迭代所处的位置 一个简单的迭代器 在这个例子中values就是工厂。每当调用这个工厂时它就会创建一个新的闭包即迭代器本身。这个闭包将它的状态保存在其外部的变量t和i中这两个变量也是由values创建的。每次调用这个迭代器时它就从列表t中返回下一个值。在遍历完最后一个元素后迭代器返回nil表示迭代结束。 泛型for的语法 泛型for在循环过程中在其内部保存了迭代函数。实际上泛型for保存了三个值一个迭代函数、一个不可变状态invariant state和一个控制变量control variable 无状态迭代器 无状态迭代器stateless iterator就是一种自身不保存任何状态的迭代器。因此可以在多个循环中使用同一个无状态迭代器从而避免创建新闭包的开销。 迭代的状态由正在被遍历的表一个不可变状态它不会在循环中改变及当前的索引值控制变量组成。 还有一种创建迭代器的方式可以让迭代器进行实际的迭代操作。当使用这种迭代器时就不再需要编写循环了。相反只需要调用这个迭代器并传入一个描述了在每次迭代时迭代器需要做什么的参数即可。更确切地说迭代器接收一个函数作为参数这个函数在循环的内部被调用这种迭代器就被称为真正的迭代器true iterator。举一个更具体的例子让我们使用这种风格再次重写allwords迭代器 马尔可夫链算法 print(please Input N (size for the sequence of previous words):) local N tonumber(io.read()) while math.type(N) ~ integer doprint(Invalid type, ReInput N:)N tonumber(io.read()) endfunction allwords ()local line io.read() -- current linelocal pos 1 -- current position in the linereturn function()-- iterator functionwhile line and line ~ do-- repeat while there are lineslocal w, e string.match(line, (%w[,;.:]?)(), pos)if w then-- found a word?pos e -- update next positionreturn w -- return the wordelseline io.read() -- word not found; try next linepos 1 -- restart from first positionendendreturn nil -- no more lines: end of traversalend endfunction prefix (words)return table.concat(words, ) endlocal statetab {}function insert (prefix, value)local list statetab[prefix]if list nil thenstatetab[prefix] { value }elselist[#list 1] valueend endlocal MAXGEN 200 local NOWORD \n-- build table local wordTable {} for i 1,N dowordTable[N] NOWORD end print(\nPlease Input the words:) for nextword in allwords() doinsert(prefix(wordTable), nextword)for i 1,#wordTable dowordTable[i] wordTable[i 1]endwordTable[N] nextword end insert(prefix(wordTable), NOWORD)-- generate text for i 1,N dowordTable[N] NOWORD end for i 1, MAXGEN dolocal list statetab[prefix(wordTable)]-- choose a random item from listlocal r math.random(#list)local nextword list[r]if nextword NOWORD thenreturnendio.write(nextword, )for i 1,#wordTable dowordTable[i] wordTable[i 1]endwordTable[N] nextword end pil4/chapter19/chapter19.lua at master · 0kk470/pil4 (github.com) 元表和元方法 元表可以修改一个值在面对一个未知操作时的行为 例如假设a和b都是表那么可以通过元表定义Lua语言如何计算表达式ab。当Lua语言试图将两个表相加时它会先检查两者之一是否有元表metatable且该元表中是否有__add字段。如果Lua语言找到了该字段就调用该字段对应的值即所谓的元方法metamethod是一个函数 可以认为元表是面向对象领域中的受限制类。像类一样元表定义的是实例的行为。不过由于元表只能给出预先定义的操作集合的行为所以元表比类更受限同时元表也不支持继承 Lua语言中的每一个值都可以有元表。每一个表和用户数据类型都具有各自独立的元表而其他类型的值则共享对应类型所属的同一个元表。Lua语言在创建新表时不带元表 可以使用函数setmetatable来设置或修改任意表的元表 在Lua语言中我们只能为表设置元表如果要为其他类型的值设置元表则必须通过C代码或调试库完成 字符串标准库为所有的字符串都设罝了同一个元表而其他类型在默认情况中都没有元表 一个表可以成为任意值的元表一组相关的表也可以共享一个描述了它们共同行为的通用元表一个表还可以成为它自己的元表用于描述其自身特有的行为。总之任何配置都是合法的。 算术运算相关的元方法 现在假设想使用加法操作符来计算两个集合的并集那么可以让所有表示集合的表共享一个元表。这个元表中定义了这些表应该如何执行加法操作。首先我们创建一个普通的表这个表被用作集合的元表 然后修改用于创建集合的函数Set.new。在新版本中只多了一行即将mt设置为函数Set.new所创建的表的元表 在此之后所有由Set.new创建的集合都具有了一个相同的元表 最后向元表中加入元方法metamethod__add也就是用于描述如何完成加法的字段 此后只要Lua语言试图将两个集合相加它就会调用函数Set.union并将两个操作数作为参数传入。 关系运算相关的元方法 元表还允许我们指定关系运算符的含义其中的元方法包括等于__eq、小于__lt和小于等于__le。其他三个关系运算符没有单独的元方法Lua语言会将ab转换为notabab转换为baab转换为ba。 部分有序是指并非所有类型的元素都能够被正确地排序。例如由于Not a NumberNaN的存在大多数计算机中的浮点数就不是完全可以排序的。 标准规定任何涉及NaN的比较都应返回假这就意味着NaNx永远为假xNaN也为假。因此在这种情况下ab到notba的转化也就不合法了。 在集合的示例中我们也面临类似的问题。显而易见且有用的含义是集合包含ab通常意味着a是b的一个子集。然而根据部分有序的定义ab和ba可能同时为假。因此我们就必须实现__le小于等于子集关系和__lt小于真子集关系 表相关的元方法 算术运算符、位运算符和关系运算符的元方法都定义了各种错误情况的行为但它们都没有改变语言的正常行为。Lua语言还提供了一种改变表在两种正常情况下的行为的方式即访问和修改表中不存在的字段。 __index元方法 对表的访问会引发解释器查找一个名为__index的元方法。如果没有这个元方法那么像一般情况下元素不存在的情况一样结果就是nil否则则由这个元方法来提供最终结果。 ---[[ --创建具有默认值的原型 prototype {x 0,y 0,width 100,height 100}local mt {} --创建一个元表 --声明构造函数 function new(o)setmetatable(o,mt)return o endmt.__index function (_,key )return prototype[key] endw new{x 10,y 20} print(w.width) --]] 输出100 Lua语言会发现w中没有对应的字段width但却有一个带有__index元方法的元表。因此Lua语言会以w表和width不存在的键为参数来调用这个元方法。元方法随后会用这个键来检索原型并返回结果。 在Lua语言中使用元方法__index来实现继承是很普遍的方法。虽然被叫作方法但元方法__index不一定必须是一个函数它还可以是一个表。当元方法是一个函数时Lua语言会以表和不存在的键为参数调用该函数正如我们刚刚所看到的。当元方法是一个表时Lua语言就访问这个表。因此在我们此前的示例中可以把__index简单地声明为如下样式 mt.__index    prototype 如果我们希望在访问一个表时不调用__index元方法那么可以使用函数rawget。调用rawgett,i会对表t进行原始raw的访问即在不考虑元表的情况下对表进行简单的访问 __newindex元方法 元方法__newindex与__index类似不同之处在于前者用于表的更新而后者用于表的查询。当对一个表中不存在的索引赋值时解释器就会查找__newindex元方法如果这个元方法存在那么解释器就调用它而不执行赋值。像元方法__index一样如果这个元方法是一个表解释器就在此表中执行赋值而不是在原始的表中进行赋值。此外还有一个原始函数允许我们绕过元方法调用rawsett,k,v来等价于t[k]v但不涉及任何元方法 具有默认值的表 一个普通表中所有字段的默认值都是nil。通过元表可以很容易地修改这个默认值 跟踪对表的访问 假设我们要跟踪对某个表的所有访问。由于__index和__newindex元方法都是在表中的索引不存在时才有用因此捕获对一个表所有访问的唯一方式是保持表是空的。如果要监控对一个表的所有访问那么需要为真正的表创建一个代理proxy。这个代理是一个空的表具有用于跟踪所有访问并将访问重定向到原来的表的合理元方法 ---[[ function track(t)local proxy {} --t的代理类--为代理创建元表local mt {__index function(_,k)print(*access to element .. tostring(k))return t[k] --访问原来的表 end,__newindex function ( _,k,v )print(*update of element .. tostring(k) .. to .. tostring(v))t[k] v --更新原来的表end__pairs function( )return function(_,k) --迭代函数local nextkey,nextvalue next(t,k)if nextkey ~ nil then --避免最后一个值print(*traversing element .. tostring(nextkey))endreturn nextkey,nextvalueendend,__len function() return #t end}setmetable(proxy,mt)return proxy endt {} t track(t) t[2] hello print(t[2])--]] 只读的表 面向对象Object-Oriented编程 从很多意义上讲Lua语言中的一张表就是一个对象。首先表与对象一样可以拥有状态。其次表与对象一样拥有一个与其值无关的的标识self -- 类似于 this 指针特别地两个具有相同值的对象表是两个不同的对象而一个对象可以具有多个不同的值最后表与对象一样具有与创建者和被创建位置无关的生命周期。 对象有其自己的操作。表也可以有自己的操作例如 上面的代码创建了一个新函数并将该函数存入Account对象的withdraw字段。 不过在函数中使用全局名称Account是一个非常糟糕的编程习惯。首先这个函数只能针对特定对象工作。其次即使针对特定的对象这个函数也只有在对象保存在特定的全局变量中时才能工作。如果我们改变了对象的名称withdraw就不能工作了 这种行为违反对象拥有独立生命周期的原则。 另一种更加有原则的方法是对操作的接受者receiver进行操作。因此我们的方法需要一个额外的参数来表示该接受者这个参数通常被称为self或this 此时当我们调用该方法时必须指定要操作的对象 通过使用参数self可以对多个对象调用相同的方法 Lua语言可以使用冒号操作符colon operator隐藏self参数。使用冒号操作符我们可以将上例重写为a2:withdraw260.00 我们可以使用点分语法来定义一个函数然后用冒号语法调用它反之亦然只要能够正确地处理好额外的参数即可 类Class 我们可以参考基于原型的语言prototype-based language中的一些做法来在Lua语言中模拟类例如Self语言JavaScript采用的也是这种方式。在这些语言中对象不属于类。相反每个对象可以有一个原型prototype。原型也是一种普通的对象当对象类的实例遇到一个未知操作时会首先在原型中查找。要在这种语言中表示一个类我们只需要创建一个专门被用作其他对象类的实例的原型对象即可。类和原型都是一种组织多个对象间共享行为的方式。 如果有两个对象A和B要让B成为A的一个原型只需要 即Lua语言调用了原来的deposit函数传入了a作为self参数。因此新账户a从Account继承了函数deposit。同样它还从Account继承了所有的字段。 继承Inheritance 多重继承Multiple Inheritance 这种实现的关键在于把一个函数用作__index元方法。请注意当一个表的元表中的__index字段为一个函数时当Lua不能在原来的表中找到一个键时就会调用这个函数。基于这一点就可以让__index元方法在其他期望的任意数量的父类中查找缺失的键。 多重继承意味着一个类可以具有多个超类。因此我们不应该使用一个超类中的方法来创建子类而是应该定义一个独立的函数createClass来创建子类。函数createClass的参数为新类的所有超类 --在表‘plist’的列表中查找‘k’ local function search( k,plist )for i 1,#plist dolocal v plist[i][k] --尝试第‘i’个超类if v then return v end end endfunction ccreateClass( ... )local c {} --新类local parents {...} --父类列表--在父类列表中查找类缺失的方法setmetatable(c,{__index function(t,k)return search(k,parents)end })--将‘c’作为其实例的元素c.__index c--为新类定义一个新的构造函数function c:new(o)o o or {}setmetatable(o,c)return oendreturn c -- 返回新类 end 私有性Privacy 一个表用来保存对象的状态另一个表用于保存对象的操作或接口。我们通过第二个表来访问对象本身即通过组成其接口的操作来访问。为了避免未授权的访问表示对象状态的表不保存在其他表的字段中而只保存在方法的闭包中。例如如果要用这种设计来表示银行账户那么可以通过下面的工厂函数创建新的对象 首先这个函数创建了一个用于保存对象内部状态的表并将其存储在局部变量self中。然后这个函数创建了对象的方法。最后这个函数会创建并返回一个外部对象该对象将方法名与真正的方法实现映射起来。这里的关键在于这些方法不需要额外的self参数而是直接访问self变量。由于没有了额外的参数我们也就无须使用冒号语法来操作这些对象而是可以像普通函数那样来调用这些方法 这种设计给予了存储在表self中所有内容完全的私有性。当newAccount返回后就无法直接访问这个表了我们只能通过在newAccount中创建的函数来访问它 单方法对象Single-method Object 上述面向对象编程实现的一个特例是对象只有一个方法的情况。在这种情况下可以不用创建接口表只要将这个单独的方法以对象的表示形式返回即可。诸如io.lines或string.gmatch这样的内部保存了状态的迭代器就是一个单方法对象。 虽然使用这种方式不能实现继承但我们却可以拥有完全的私有性访问单方法对象中某个成员只能通过该对象所具有的唯一方法进行。 对偶表示Dual Representation 实现私有性的另一种有趣方式是使用对偶表示dual representation
http://www.ho-use.cn/article/10817313.html

相关文章:

  • 美乐乐网站首页如何修改做网站的空间和服务器
  • 电商网站服务排名武宁县建设工程招标公告门户网站
  • 网站密码忘记了怎么办做网站汉狮网络
  • 网站关键词提升市场调研公司和咨询公司
  • 洛阳制作网站哪家好绵竹seo
  • 当牛做吗网站源代码分享做视频找空镜头那个网站比较全
  • 网站怎么收费动画设计招聘信息
  • 网站建设销售渠道全球门户中企动力
  • 缠绕机东莞网站建设技术支持淘宝运营工作内容
  • 网站优化升级网站开发必看书籍
  • wordpress建站多个域名北京网站建设手机号
  • 网站模板修改器微信公众号怎么创建要多少钱
  • 360元网站建设 网络服务wordpress能注册
  • 网站开发如何赚钱网页设计师是什么专业
  • 做什麽网站有前景网站开发流程原理
  • html网页制作内容网站做301对优化有影响
  • 浙江嘉兴网站建设凌河建设网站
  • 企业网站建设设计任务书排版设计网站有哪些
  • 高端网站制作费用怎么做wordpress主题
  • 比较好的做网站公司微网站 pc网站同步
  • 网站横幅怎做用wordPress搭建图片库
  • 网站开发系统流程图如何做好网络宣传工作
  • 企业网站推广工具做国际网站阿里巴巴
  • 做网站三河百度竞价员
  • 网站建设服务谁便宜大气的个人网站
  • 织梦网站做图床手机网站指向什么意思
  • 网站建设公司走进深圳易百讯网站内链怎么布局
  • 做的美食视频网站新手小白怎样运营1688店铺
  • 域名对网站的好处网站宣传视频
  • 佛山网站建设费用服装品牌网站建设