Lua学习笔记

neovim 0.5正式版本已经发布了,现在学习Lua语言还来的及吧。lua替换vim脚本渐渐成为了趋势了。

Lua学习下来,感觉与javascript特别的像。就是代码块不是使用{}分割,而是end,需要习惯一下。代码阅读问题不大,自己写代码还是要适应一下。

Lua中有一些好玩的语法,用起来比Java,Javascript简单,爽!

我学习的教程文档:
https://www.lua.org/pil/contents.html

文章写的简单明了,推荐阅读。

文章目录

  • table.sort排序
    • ip地址按名称排序
    • 学生按年级排序
    • 学生按年级自定义函数排序
  • Closures
    • Lua版本
    • Javascript版本
    • Java版本
  • Non-Global Functions
    • 写法
    • 递归局部函数的定义
  • 相关文档

table.sort排序

ip地址按名称排序

network = {
	{name = "grauna",  IP = "210.26.30.34"},
	{name = "arraial", IP = "210.26.30.23"},
	{name = "lua",     IP = "210.26.23.12"},
	{name = "derain",  IP = "210.26.23.20"},
}


table.sort(network,function (a,b)
	return (a.name > b.name)
end)

print("输出")
for _,line in ipairs(network) do
	print(line.name)
end

学生按年级排序

names = {"Peter","Paul","Mary"}
grades= {Mary =10,Paul =7,Peter=8}

table.sort(names,function (n1, n2)
	return grades[n1] > grades[n2]
end)

print("------输出排序结果------")
for _,line in ipairs(names) do
	print(line)
end

学生按年级自定义函数排序

示例中有趣的一点是给定的匿名函数sort 访问参数grades,该参数对于封闭函数来说是本地的sortbygrade。在这个匿名函数内部, grades既不是全局变量也不是局部变量。我们称它为外部局部变量或upvalue。(术语“upvalue”有点误导,因为它grades是一个变量,而不是一个值。然而,这个术语在 Lua 中有历史渊源,它比“外部局部变量”短。)

names = {"Peter","Paul","Mary"}
grades= {Mary =10,Paul =7,Peter=8}

function sortbygrade(names,grades)
	table.sort(names,function(n1,n2)
		return grades[n1] > grades[n2]
	end)
end

sortbygrade(names,grades)

print("------输出排序结果------")
for _,line in ipairs(names) do
	print(line)
end

https://www.lua.org/pil/6.1.html

Closures

Lua版本

这个特性跟我想像的不太一样。

So, c1 and c2 are different closures over the same function and each acts upon an independent instantiation of the local variable i. Technically speaking, what is a value in Lua is the closure, not the function. The function itself is just a prototype for closures. Nevertheless, we will continue to use the term “function” to refer to a closure whenever there is no possibility of confusion.

因此,c1和c2是同一函数上的不同闭包,每个闭包都作用于局部变量的独立实例化i。从技术上讲,Lua 中的值是闭包,而不是函数。函数本身只是闭包的原型。尽管如此,只要没有混淆的可能性,我们将继续使用术语“函数”来指代闭包。

function newCounter()
	local i = 0
	return function () --匿名函数
		i = i + 1
		return i
	end
end

c1 = newCounter()
print(c1()) -->1
print(c1()) -->2

c2 = newCounter()
print(c2())  -->1
print(c1())  -->3
print(c2())  -->2

这样的写法我以前基本没用过,为了测试我的理解,我写了个javascript版本的。执行结果竟然一样的。看来是我一直理解的有问题。

Javascript版本

结果与Lua版本一至。

function newCounter(){
	let i = 0;
	return function(){
		i = i+1;
		return i;
	}
}

let c1 = newCounter()
console.log(c1()); //>1
console.log(c1()); //>2

let c2=newCounter()
console.log(c2());//>1
console.log(c1());//>3
console.log(c2());//>2

Java版本

我就思考如何在java中写出类似的代码呢?Java中好像没有匿名方法吧?

	public static void main(String[] args) {
        System.out.println(newCounter());//>1
        System.out.println(newCounter());//>1
        System.out.println(newCounter());//>1
    }

    public static int newCounter() {
        int i = 0;
        return i + 1;
    }

显然这样写是不对的,估计要用匿名内部类的方式处理吧。
为了模拟上面的逻辑,我使用java中的类实现。执行结果一至。

public class Main {
    public static void main(String[] args) {
        class NewCounter{
            int i =0;
            public NewCounter() {
            }
            @Override
            public String toString() {
                i = i+1;
                return String.valueOf(i);
            }
        }
        NewCounter c1 = new NewCounter();
        System.out.println(c1);//>1
        System.out.println(c1);//>2

        NewCounter c2 = new NewCounter();
        System.out.println(c2);//>1
        System.out.println(c1);//>3
        System.out.println(c2);//>2
    }
}

总结:
Closures中的变量感觉类似与Java中的类属性,很个实例单独管理。

Non-Global Functions

写法

Lib = {}
    Lib.foo = function (x,y) return x + y end
    Lib.goo = function (x,y) return x - y end

 Lib = {
      foo = function (x,y) return x + y end,
      goo = function (x,y) return x - y end
    }

Lib = {}
    function Lib.foo (x,y)
      return x + y
    end
    function Lib.goo (x,y)
      return x - y
    end

递归局部函数的定义

错误的❌

local fact = function (n)
      if n == 0 then return 1
      else return n*fact(n-1)   -- buggy
      end
    end

正确✅

 local fact
    fact = function (n)
      if n == 0 then return 1
      else return n*fact(n-1)
      end
    end

现在fact函数内部指的是局部变量。它在定义函数时的值无关紧要;到函数执行时, fact已经有了正确的值。这就是 Lua 为本地函数扩展其语法糖的方式,因此您可以将其用于递归函数而无需担心:

 local function fact (n)
      if n == 0 then return 1
      else return n*fact(n-1)
      end
    end

相关文档

https://www.lua.org/pil/contents.html#P1

你可能感兴趣的:(笔记,lua)