前言:

语言学起来其实相似点很多,简单整理的知识点

目录:

1.使用控制台

2.Lua基础

3.变量

4.运算符

5.控制结构

1.使用控制台

Lua脚本是包含一系列Lua命令的简单脚本(扩展名为.lua的文本文件)。Lua不关注格式,制表符,换行符或者其他让脚本文件更具可读性的转换符号(不过Lua还是需要命令之间的空格符号,用来区别变量和函数调用)

简单的Lua脚本:

for indx = 1,4 do

print("line:",indx )

end

也可以写成:for indx = 1,4 do print("line:",indx ) end

注:

格式化后的脚本更容易阅读,但不改变结果

可以把脚本放在本地文件夹通过dofile命令来在控制台执行脚本,参数是字符串,指定文件的名字和路径。使用dofile命令可以在命令行中运行脚本,如果脚本有什么错误的化,命令行会给出错误信息以便调试。

语法格式:

dofile<"c:\\file_name\\lua_scripts_name.lua">

2.Lua基础

优势:整合C++的模块来扩展自身的功能。

语言定义

不以数字为标识符开头(同C),避免下划线接大写字母(_NAME),因为这种格式是Lua自身保留的(保留字),如_Start。

Lua保留关键字

and    local    break    nil    do

not    else    or    elseif    repeat

end    return    false    then    for

true    function    until    if    while

in

变量,常量,函数名的格式和命名规则:

常用全大写和下划线(MY_NAME)

变量第一个字母小写(myVariable)

全局变量第一个字母用小写(gMyGlobal)

函数名第一个字母大写(function  MyFunction)

--单行注释

--[[
     statements    块注释

--]]

使用技巧:--[[ 或者 --]]  加一个 - 可以重新使用这段代码  ---[[   ---]]

3.变量

在Lua中,变量不需要在使用前声明,这个稍微有些争议。因为不需要声明,所以可以才任何地方引入需要的变量。由于不是显式声明,所以很难追踪变量(不造),或者在另一个函数中用了相同名字的变量而造成数据的混乱。因此,必须小心的使用变量,要保证变量是可追踪的。同样不需要指定变量类型,变量类型取决于给变量赋的值,灵活性较高。

变量赋值:

1.赋值改变

2.改变表域

多个变量同时赋值时赋值变量列表和值列表的各个元素用逗号分开,依次赋值。

a,b=1,2

遇到赋值语句Lua会先计算右边所有的值然后在执行赋值操作,所以我们可以这样进行交换变量的值。

x,y=y,x

当变量个数与值个数不一致时,Lua会以变量个数为基础,采取不足补nil,多的忽略。

例:

a,b,c=0,1   --->0,1,nil

a,b,c=0,1,2,3 --->0,1,2

多值赋值常用来交换变量,或将函数调用返回给变量。

例:

a, b = f()

f()返回两个值,第一个赋给a,第二个赋给b。

应该尽可能的使用局部变量,有两个好处:

1. 避免命名冲突。

2. 访问局部变量的速度比全局变量更快。

索引

对 table 的索引使用方括号 []。Lua 也提供了 . 操作。

t[i]

t.i                 -- 当索引为字符串类型时的一种简化写法

gettable_event(t,i) -- 采用索引访问本质上是一个类似这样的函数调用

例如:

> site = {}

> site["key"] = "www.w3cschool.cc"

> print(site["key"])

www.w3cschool.cc

> print(site.key)

www.w3cschool.cc

变量类型:

注:可以使用Type函数测试变量的类型。

3.1 nil

nil 表示没赋值的变量,实际上可以表示删除变量。

3.2Boolean

Boolean类型的变量只有两种值 :true和false.

3.3string

3.3.1用两个方括号也可以表示一块字符串

特殊字符串:

\a    响铃    \v    垂直指标

\b    退格    \\    反斜杠

\f    换页符    \"    双引号

\n    换行符    \'    单引号

\r    换行符    \[    左方括号

\t    制表符    \]    右方括号

\o    空字符    \ddd    八进制

\xhh    十六进制

3.3.2在对一个数字字符串进行操作时,Lua会将这个数字字符串转换成一个数字。

例子:

print(2+6)--8

print("2"+6)--8

print("2"+"6")--8

print("2+6")--2+6

print("abc"+6)--报错,字符串连接不是用+而是两点 ..

print("2"..6)--26

注:..(连接字符串)
       #(计算字符串长度,置于字符串前或者变量名前)

3.4Number

双精度浮点数,无整数类型

myNumber=7

myNumber=0.765

myNumber=7.65e8(7.65x10^8,765 000 000)

myNumber=7.65e-2(7.65x10^-2,0.0765)

3.5table

3.5.1实质是关联数组(associative arrays)索引为数字或字符串,初始索引为1.

3.5.2table的创建

3.5.2.1空表

local tab1={}

3.5.2.2初始表

local tab2={"apple","pear"}

注:table不会固定长度大小,有新数据添加时,table会自动增长,没有初始值都为nil.

3.6局部变量和全局变量

Lua变量默认是全局的,也就是说,变量的值在整个会话中是保持不变的,除非脚本改变了它。

当使用全局变量时,变量名前加一个g字母会更加明确,便于调试。

局部变量可以给设定一个初始值,也可以不用赋值。

语法:

local 变量名

变量的有效范围取决于声明变量的位置。

4.运算符

4.1算术运算符

+-*/%^-

4.2关系运算符

==

~=

>

<

>=

<=

注:如果使用关系运算符比较两个table,只有两个table是同一个对象的时候才能得到预期的结果,因为变量只是table对象的引用(像指针一样),不能直接比较存在于table中的值。

实例:

tableA={1,2,3}

tableB={1,2,3}

if tableA=tableB then
     print("相等")

else
     print("不相等")

end

-->不相等(结构不同)

tableA={1,2,3}

tableB=tableA

if tableA=tableB then
     print("相等")

else
     print("不相等")

end

-->相等(tableB指向了同样的对象tableA)

4.3逻辑运算符

and(比较两个参数时,第一个false则返回flase,否则返回第二个参数的值)

or

not

注:官方解释的是一坨屎,就和C一样理解就行。

4.4其他运算符

.. 连接字符串

#一元运算符,返回字符串或表的长度

4.5运算符的优先级

从高到低的顺序:

^

not    - (unary)

*      /

+      -

..

<      >      <=     >=     ~=     ==

and

or

注:

除了^和..外所有的二元运算符都是左连接的。

a+i < b/2+1          <-->       (a+i) < ((b/2)+1)

5+x^2*8              <-->       5+((x^2)*8)

a < y and y <= z     <-->       (a < y) and (y <= z)

-x^2                 <-->       -(x^2)

x^y^z                <-->       x^(y^z)

实例

我们可以通过以下实例来更加透彻的了解 Lua 语言运算符的优先级:

a = 20

b = 10

c = 15

d = 5

e = (a + b) * c / d;-- ( 30 * 15 ) / 5

print("(a + b) * c / d 运算值为  :",e )

e = ((a + b) * c) / d; -- (30 * 15 ) / 5

print("((a + b) * c) / d 运算值为 :",e )

e = (a + b) * (c / d);-- (30) * (15/5)

print("(a + b) * (c / d) 运算值为 :",e )

e = a + (b * c) / d;  -- 20 + (150/5)

print("a + (b * c) / d 运算值为   :",e )

以上程序执行结果为:

(a + b) * c / d 运算值为  :    90.0

((a + b) * c) / d 运算值为 :    90.0

(a + b) * (c / d) 运算值为 :    90.0

a + (b * c) / d 运算值为   :    50.0

注:除了^和..外所有二元运算符都是左连接的。

笔记:

1.在Lua中实现C/C++中的三目运算。

condition?  result1:result2

|

if  condition then

return result1

else

return result2

end

三目运算

熟悉 C/C++ 的老司机都知道三目运算 a ? b : c,这种写法替换简单的条件判断语句可以在不增加阅读难度的情况下,使代码尽量保持简洁。

int a, b, ret;

//if-else

if (a > b)
     ret = a;

else
     ret = b;

//三目运算符

ret = a > b ? a : b;

Lua 中的三目运算

Lua 原生的语义并没有实现三目运算,一般是通过逻辑运算符 and 和 or 来模拟三目运算符的。

Lua 中 and 和 or 都使用"短路求值(short_cur evaluation)",也就是说,它们只会在需要时才去评估第二个操作数。(《Lua程序设计》)

local a, b, ret;

ret = a > b and a or b

穷举所有可能性:

a > b 时:

a > b and a –> true

a or b –> a

a <= b时:

a > b and a –> false

a or b –> b

完美!

Lua 中的三目运算符陷阱

按照从特殊到一般的原则:

三目运算的一般形式a ? b : c

a = true,结果为b

a = false,结果为c

对应Lua中的a and b or c

b = true

a = true

a and b –> true

b or c –> b

a = false

a and b –> false

b or c –> c

b = false

a = true

a and b –> false

b or c –> c

a = false

a and b –> false

b or c –> c

可以看到当 b = false 时,Lua模拟的 a and b or c 始终返回 c 并不能还原三目运算符的原貌。

《Lua程序设计》也建议这种情况使用 if-else 来避免。

一般化的 a and b or c

那么有没有办法可以解决 b = false 失效的问题呢?

由此我联想到 C 语言有一道常规的考题:请使用宏定义写一个返回两个值中较小值的方法。

在校时第一次看到本题,第一反应如下:

#define MIN(A,B) A < B ? A : B

然而这种写法在很多嵌套的使用环境中都不能返回正确的结果。比如:2 * MIN(3, 4)展开为 2 * 3 < 4 ? 3 : 4 = 6 < 4 ? 3 : 4,结果为4。

更"工程师"的写法是:

#define MIN(A,B) ((A) < (B) ? (A) : (B))

还有好奇心的同学可以参考:宏定义的正确写法,三目运算的宏定义

从这个示例中,我就在想如何能保证 a and b or c 中 b 为真或者 b 不产生歧义呢?

and的运算优先级高于or,简单的改变运算顺序并没有用。

这时就想到了lua中万能的table,能不能把a,b,c都放到table中来改变b的存在呢?要注意{nil}也是一个为true的对象。

a,b,c都替换为table:{a} and {b} or {c}。

三目运算中a是条件,结果是b或者c。其实a并不需要放入table中,否则{a}就始终为true了,失去了条件的意义。而{b} or

{c}的结果也必然是一个table,该table只有一个元素。那么通过[1]即可访问。

综上所述,更一般化的Lua三目运算为:(a and {b} or {c})[1]

2.其他运算符 —— #

在获取表的长度时,根据的是表的最大索引的值:

tab1 = {"1","2"}

print("tab1长度"..#tab1)

tab2 = {key1="1","2"}

print("tab2长度"..#tab2)

tab3 = {}

tab3[1]="1"

tab3[2]="2"

tab3[4]="4"

print("tab3长度"..#tab3)

输出:

tab1长度2

tab2长度1

tab3长度4

3. 下标越过 1 位以上,长度还是为 2:

tab3={}

tab3[1]="1"

tab3[2]="2"

tab3[5]="5"

print("tab3的长度",#tab3)

输出:

tab3的长度    2

4.取长度操作符写作一元操作 #

table t 的长度被定义成一个整数下标 n 。 它满足 t[n] 不是 nil 而 t[n+1] 为 nil; 此外,如果 t[1] 为 nil ,n 就可能是零。 对于常规的数组,里面从 1 到 n 放着一些非空的值的时候, 它的长度就精确的为 n,即最后一个值的下标。 如果数组有一个“空洞” (就是说,nil 值被夹在非空值之间), 那么 #t 可能是指向任何一个是 nil 值的前一个位置的下标 (就是说,任何一个nil 值都有可能被当成数组的结束)。

tab4 = {}

tab4[1] = "1"

tab4[2] = nil

tab4[3] = "2"

tab4[4] = nil

print("tab4的长度", #tab4)

--tab4的长度    1

tab5 = {}

tab5[1] = "1"

tab5[2] = nil

tab5[3] = "2"

tab5[4] = "4"

print("tab5的长度", #tab5)

--tab5的长度    4

tab6 = {1, nil, 3}

print("tab6的长度", #tab6)

--tab6的长度    3

tab6 = {1, nil, 3, nil}

print("tab6的长度", #tab6)

--tab6的长度    1

5.控制结构

注:

控制结构的条件表达式结果可以是任何值,Lua认为false和nil为假,true和非nil为真。

要注意的是Lua中 0 为 true:

5.1if 语句

if 语句 由一个布尔表达式作为条件判断,其后紧跟其他语句组成。

Lua if 语句语法格式如下:

if(布尔表达式)

then
    --[ 在布尔表达式为 true 时执行的语句 --]

end

在布尔表达式为 true 时会if中的代码块会被执行,在布尔表达式为 false 时,紧跟在 if 语句 end 之后的代码会被执行。

Lua认为false和nil为假,true 和非nil为真。要注意的是Lua中 0 为 true。

5.2if...else 语句

if 语句 可以与 else 语句搭配使用, 在 if 条件表达式为 false 时执行 else 语句代码。

if...else 语句

Lua if 语句可以与 else 语句搭配使用, 在 if 条件表达式为 false 时执行 else 语句代码块。

Lua if...else 语句语法格式如下:

if(布尔表达式)

then
    --[ 布尔表达式为 true 时执行该语句块 --]

else
    --[ 布尔表达式为 false 时执行该语句块 --]

end

在布尔表达式为 true 时会if中的代码块会被执行,在布尔表达式为 false 时,else 的代码块会被执行。

Lua认为false和nil为假,true 和非nil为真。要注意的是Lua中 0 为 true。

if...elseif...else 语句

Lua if 语句可以与 elseif...else 语句搭配使用, 在 if 条件表达式为 false 时执行 elseif...else 语句代码块,用于检测多个条件语句。

Lua if...elseif...else 语句语法格式如下:

if( 布尔表达式 1)

then
    --[ 在布尔表达式 1 为 true 时执行该语句块 --]

elseif( 布尔表达式 2)

then
    --[ 在布尔表达式 2 为 true 时执行该语句块 --]

elseif( 布尔表达式 3)

then
    --[ 在布尔表达式 3 为 true 时执行该语句块 --]

else
    --[ 如果以上布尔表达式都不为 true 则执行该语句块 --]

end

5.3if 嵌套语句

你可以在if 或 else if中使用一个或多个 if 或 else if 语句 。

if...else 语句

Lua if 语句允许嵌套, 这就意味着你可以在一个 if 或 else if 语句中插入其他的 if 或 else if 语句。

Lua if 嵌套语句语法格式如下:

if( 布尔表达式 1)

then
    --[ 布尔表达式 1 为 true 时执行该语句块 --]
    if(布尔表达式 2)
    then
       --[ 布尔表达式 2 为 true 时执行该语句块 --]
    end

end

你可以用同样的方式嵌套 else if...else 语句。

注:Lua不支持case语句因此可以用elseif语句

5.4循环

Lua 语言提供了以下几种循环处理方式:

while 循环

在条件为 true 时,让程序重复地执行某些语句。执行语句前会先检查条件是否为 true。

for 循环

重复执行指定语句,重复次数可在 for 语句中控制。

repeat...until

重复执行循环,直到 指定的条件为真时为止

循环嵌套

可以在循环内嵌套一个或多个循环语句(while do ... end;for ... do ... end;repeat ... until;)

5.4.1while

注:

while和repeat 控制结构非常相似,它们都可以循环执行一段脚本直到满足某个条件。

Lua 编程语言中 while 循环语句在判断条件为 true 时会重复执行循环体语句。

语法

Lua 编程语言中 while 循环语法:

while(condition)

do
    statements

end

5.4.2repeat

repeat...until 循环的条件语句在当前循环结束后判断。

语法

Lua 编程语言中 repeat...until 循环语法格式:

repeat
    statements

until( condition )

5.4.3for

Lua 编程语言中 for 循环语句可以重复执行指定语句,重复次数可在 for 语句中控制。

Lua 编程语言中 for语句有两大类:

数值for循环

泛型for循环

5.4.3.1数值for循环

Lua 编程语言中数值for循环语法格式:

for var=exp1,exp2,exp3 do 
     <执行体> 

end
  

var从exp1变化到exp2,每次变化以exp3为步长递增var,并执行一次"执行体"。exp3是可选的,如果不指定,默认为1。

示例:

for i=10,1,-1 do
     print(i)

end

从10变到1,每次减1

结果:10,9,8,7,6,5,4,3,2,1

5.4.3.2泛型for循环

泛型for循环通过一个迭代器函数来遍历所有值,类似java中的foreach语句。

Lua 编程语言中泛型for循环语法格式:

--打印数组a的所有值 

for i,v in ipairs(a)
     do print(v)

end 

i是数组索引值,v是对应索引的数组元素值。ipairs是Lua提供的一个迭代器函数,用来迭代数组。

days ={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"} 

for i,v in ipairs(days) do 

print(v)
  end

结果略(ipairs(为表达式列表),后面泛型for里有提到)

注:

1.循环次数只是在第一次执行时确定,因此就算用户更改了参数的值也不会影响最终的循环次数。

2.循环结构中的变量是局部变量,一旦循环结束就会被清除。如果想保存它们的值

,那么必须使用全局变量或者更高级的局部变量。

笔记:

1.

在lua中pairs与ipairs两个迭代器的用法相近,但有一点是不一样的:

pairs可以遍历表中所有的key,并且除了迭代器本身以及遍历表本身还可以返回nil;

但是ipairs则不能返回nil,只能返回数字0,如果遇到nil则退出。它只能遍历到表中出现的第一个不是整数的key

2.pairs遍历表中全部key,value

ipairs从下标为1开始遍历,然后下标累加1,如果某个下标元素不存在就终止遍历。这就导致如果下标不连续或者不是从1开始的表就会中断或者遍历不到元素。

3.

首先,ipairs 这个迭代器只能遍历所有数组下标的值,这是前提,也是和 pairs 的最根本区别,也就是说如果 ipairs 在迭代过程中是会直接跳过所有手动设定key值的变量。

特别注意一点,和其他多数语言不同的地方是,迭代的下标是从1开始的。

3.1

例如:

tab = {1,2,a= nil,"d"}

for i,v in ipairs(tab) do
     print(i,v)

end

输出结果为:

1  1

2  2

3  d

这里是直接跳过了a=nil这个变量

3.2

ipairs在迭代过程中如果遇到nil时会直接停止。

例如:

tab = {1,2,a= nil,nil,"d"}

for i,v in ipairs(tab) do
     print(i,v)

end

输出结果为:

1  1

2  2

4.

for 循环中,循环的索引 i 为外部索引,修改循环语句中的内部索引 i,不会影响循环次数:

for i=1,10 do
     i = 10
     print("one time,i:"..i)

end

仍然循环 10 次,只是 i 的值被修改了。

5.5嵌套循环

语法

Lua 编程语言中 for 循环嵌套语法格式:

for init,max/min value, increment

do
    for init,max/min value, increment
    do
       statements
    end
    statements

end

Lua 编程语言中 while 循环嵌套语法格式:

while(condition)

do
    while(condition)
    do
       statements
    end
    statements

end

Lua 编程语言中 repeat...until 循环嵌套语法格式:

repeat
    statements
    repeat
       statements
    until( condition )

until( condition )

除了以上同类型循环嵌套外,我们还可以使用不同的循环类型来嵌套,如 for 循环体中嵌套 while 循环。

实例

以下实例使用了for循环嵌套:

j =2

for i=2,10 do
    for j=2,(i/j) , 2 do
       if(not(i%j))
       then
          break
       end
       if(j > (i/j))then
          print("i 的值为:",i)
       end
    end

end

以上代码执行结果为:

i 的值为:    8

i 的值为:    9

i 的值为:    10

5.6循环控制语句

循环控制语句用于控制程序的流程, 以实现程序的各种结构方式。

Lua 支持以下循环控制语句:

break 语句

退出当前循环或语句,并开始脚本执行紧接着的语句。

5.7无限循环

在循环体中如果条件永远为 true 循环语句就会永远执行下去,以下以 while 循环为例:

while( true )

do
    print("循环将永远执行下去")

end

02Lua入门的更多相关文章

  1. Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求

    上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...

  2. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  3. Oracle分析函数入门

    一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计 ...

  4. Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数

    上一篇:Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数 之前介绍了简单的路由以及传参,这篇文章我们将要学习复杂一些的路由以及传递其他附加参数.一个好的路由系统可以使我们 ...

  5. Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数

    上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...

  6. Angular2入门系列教程4-服务

    上一篇文章 Angular2入门系列教程-多个组件,主从关系 在编程中,我们通常会将数据提供单独分离出来,以免在编写程序的过程中反复复制粘贴数据请求的代码 Angular2中提供了依赖注入的概念,使得 ...

  7. wepack+sass+vue 入门教程(三)

    十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...

  8. wepack+sass+vue 入门教程(二)

    六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...

  9. wepack+sass+vue 入门教程(一)

    一.安装node.js node.js是基础,必须先安装.而且最新版的node.js,已经集成了npm. 下载地址 node安装,一路按默认即可. 二.全局安装webpack npm install ...

随机推荐

  1. mysql特殊查询----分组后排序

    使用的示例表 学生表----student 表结构 数据 查询方法 一.第一种方法 我认为这是比较传统,比较容易理解的一种方式,使用自连接,并在连接条件中作比较,之后再对查询条件分组统计,排序. se ...

  2. gitbook 入门教程之实用插件(新增3个插件)

    插件没有什么逻辑顺序,大家可以按照目录大纲直接定位到感兴趣的插件部分阅读即可. 更多插件正在陆续更新中,敬请期待... 最新更新插件 tbfed-pagefooter 版权页脚插件 gitalk 评论 ...

  3. SCSS 在项目中的运用

    最后一段时间一直在做一些网站或是CMS的项目,想用bootstrap,但是,设计那哥们说了,用什么都行,就不能用bootstrap,我去了个..... 无语中,逼着自己写.说实话,就是用bootstr ...

  4. python爬虫实战:利用scrapy,短短50行代码下载整站短视频

    近日,有朋友向我求助一件小事儿,他在一个短视频app上看到一个好玩儿的段子,想下载下来,可死活找不到下载的方法.这忙我得帮,少不得就抓包分析了一下这个app,找到了视频的下载链接,帮他解决了这个小问题 ...

  5. mysql免安装版初次使用

    在自己电脑上安装一个mysql数据库并启动,碰到一些问题,总结一下 1.下载免安装版mysql数据库,百度下载了了5.7.25版本 2.在bin文件夹下找到my-defaults.ini文件,我这没有 ...

  6. Win10 - MySQL 10061 错误

    Win10 - MySQL 10061 错误 报错内容为: Can't connect to MySQL server on localhost (10061) 参考 : MySQL问题记录--Can ...

  7. python离线安装包

    一.用download命令离线下载包  *.whl , 这个方法好像python3.7以上才能用 那么我的requirement.txt内容就是: django==1.8.11 simplejson= ...

  8. linux用户身份和文件权限

    1.用户身份与能力 root管理员是linux 的超级用户,他拥有系统的所有权,能够管理系统的各项功能,如添加/删除用户,启动/关闭服务进程,开启/禁用硬件设备…… "Linux系统中的管理 ...

  9. [LeetCode] 5. 最长回文子串

    题目链接:https://leetcode-cn.com/problems/longest-palindromic-substring/ 题目描述: 给定一个字符串 s,找到 s 中最长的回文子串.你 ...

  10. 深入理解Fabric环境搭建的详细过程

    博主之前的文章都是教大家怎么快速的搭建一个Fabric的环境,但是其中大量的工作都隐藏到了官方的脚本中,并不方便大家深入理解其中的过程,所以博主这里就将其中的过程一步步分解,方便大家! 前面的准备工作 ...