lua 给userdata设置元表_lua学习之复习汇总篇

affe2d04b9df6db868544d80ec190084.png

第六日笔记

1. 基础概念

程序块

定义

  1. 在 lua 中任何一个源代码文件或在交互模式中输入的一行代码
  2. 程序块可以是任意大小的
  3. 程序块可以是一连串语句或一条命令
  4. 也可由函数定义构成,一般将函数定义写在文件中,然后用解释器执行这个文件
  5. 换行在代码中不起任何作用,只是为了提升可读性
  6. 分隔符 ; 起分隔作用
a = a * 2 b = a * b​a = a * 2;b = a * b​a = a * b; b = a * ba = a * b b = a * b

交互模式

在交互模式中输入的一行内容会被解释器当作一个完整的程序块,如果这一行的内容不足以构成一个完整的程序块,就会等待输入

退出交互模式
  1. Ctrl + Z 是 end-of-file 控制字符,在 dos 中是这个快捷键
  2. os.exit() 标准库中的退出函数

区域设置

  1. lua 中识别什么是字母是通过区域设置来判别的
  2. 如设置希腊,就可以识别希腊字母作为变量
  3. 但在不支持该区域的系统上无法执行

执行函数文件

  1. lua 函数文件路径
  2. dofile("文件路径 / 需要转义") 加载函数库
-- 阶乘函数function fact(n)     if n == 0   then        return 1 --0 的阶乘是 1    else        return n * fact(n - 1) -- 3 的阶乘, 3 * 2 * 1    endendprint("Enter a number:")a = io.read("*number")  -- 读取用户输入且需为数字类型的print(fact(a)) --调用阶乘函数,并传入实参 a ​-- lib1 函数库function norm(x, y)    return (x ^ 2 + y ^ 2) ^ 0.5  -- 两个数的平方和再开平方根endfunction twice(x)    return 2 * x -- 一个数的两倍end

标识符

定义

  1. 由任意数字、字母、下划线构成的字符串叫做标识符
  2. 标识符不能由数字开头
  3. 标识符不能以下划线开头后跟多个大写字母
  4. 如: _PROMPT, _VERSION
  5. lua 将它们保留用作特殊用途,被称为哑变量
_PROMPT = ">lua"  -- 修改交互模式中的提示符,默认为 >

保留字

流程控制
  1. if
  2. then
  3. elseif
  4. end
  5. for
  6. do
  7. in
  8. while
  9. repeat
  10. until
if 条件表达式 then    elseif 条件表达式 thenendfor 控制变量, 终止变量, 步长 do    enda = {}for i,v in ipairs(a) do    endwhile i < 10 do    i = i + 1    print(i)endrepeat    i = 0    i = i + 1until i > 10
条件控制
  1. true
  2. false
逻辑控制
  1. and
  2. or
  3. not
类型
  1. function
  2. local
  3. nil
需要注意的点
  1. nil == nil 是相等的
  2. and 和 And 不同,lua 区分大小写
  3. lua 中条件值不仅仅只有 true 和 false
  4. 在 lua 中任何值除了 false 和 nil 都可以用作表示「真」
  5. 包括空字符串 "" 和数字 0

注释

  1. 单行注释 --
  2. 多行注释 --[[]]
  3. 使多行注释中的代码生效 ---[[ --]]
  4. 多行注释中包含多行注释 --[==[ ]==]

全局变量

  1. 全局变量不需要声明,只需要将一个值赋给它即可
  2. lua 中可以访问一个未初始化的变量且不会发生错误
  3. 但这个未初始化的变量的值为 nil
  4. 删除全局变量赋值 nil 即可
  5. lua 将全局变量存储在一个普通的 table 中

解释器

参数

  1. -i 先执行程序块,后进入交互模式
  2. -e 直接执行代码块
  3. -l 加载库文件

解释器执行参数前

  1. 会先寻找一个叫做 LUA_INIT 的环境变量
  2. 找到了,且内容为 @文件名 的话,就执行这个文件
  3. 没找到,就假设内容为 lua 代码, 并执行

解释器运行脚本前

  1. lua 将脚本前的参数存储到 arg 这个 table 中,用作启动参数
  2. 脚本名在这个 table 中的索引为 0,其后参数依此类推
  3. 脚本名前的参数为负数索引
lua -i -e "hello" script a b arg[0] = "script"arg[1] = "a"arg[-1] = "hello"arg[-2] = "-e"arg[-3] = "-i"
  1. 在 lua 中也可以通过变长参数语法来检索脚本参数
  2. 变长参数为 ... 三个点,作为函数参数传递时表示传递所有参数

2. 类型与值

  1. lua 是动态类型语言
  2. 每个值都携带有它的类型信息

获取值的类型

  1. type() 可以返回一个值的类型名称
  2. type()的返回结果永远是 string 类型的
print(type(3)) -- numberprint(type("a")) -- stringprint(type({"a", "b", "c"})) -- tableprint(type(io.read)) -- functionprint(type(true)) -- boolean

number

  1. 实数,即双精度浮点数
  2. 可使用科学计数法,如 2e2 表示 200
  3. 可重新编译 lua,使用其他类型的值来表示数字类型,如 long
  4. tonumber() 用于将一个字符串显式的转换为数字类型

boolean

  1. 在 lua 中,有两个布尔值一个是 true 表示为「真」,一个是 false 表示为「假」
  2. 但,这两个值不是用来表示条件的唯一值,在 lua 中 除 nil 和 false 外的任何值,都可以用来表示「真」, 包括空字符串 "" 和数字 0

nil

  1. 只有一个值,nil
  2. 仅用来表示为空,表示未初始化的变量或 table 元素
  3. 也可用来删除变量或 table 元素

string

  1. 是对象,由自动内存回收器进行分配和释放
  2. 是字符序列,是8位编码
  3. 可以包含数值编码,如二进制
  4. lua 中的字符串是唯一不可变的值
  5. .. 字符串连接符,用于连接两个字符串,但数字类型使用时需要用空格隔开
  6. # 长度操作符,后跟字符串,可以获取字符串长度
  7. [[]] 在期内的特殊字符不需要转义
  8. [==[ ]==] 可以正确打印多行注释的内容
  9. "3" + 4 这样的值会是 number 类型,发生了运行时隐式转换
print("97" == "a") -- 在 ASCII 编码表中,97 表示为 aprint(type(3 .. "")) -- stringprint(3..4) --报错print(3 .. 4) -- 34print(#"hello") -- 5​-- 获取子串,证明字符串是不可变的值a = "hello"b = a .. " ,world"print(a) -- helloprint(b) -- hello, worlda = [[            芜湖            ]]a = [==[    --[[        print("多行注释")        print("多行注释")    ]]]==]print(type("3" + 4)) -- number

显式转换为字符串

  1. tostring()
  2. .. "" 任意数字连接一个空字符串即可转换为字符串

table

  1. 是对象,由自动内存回收器进行分配和释放
  2. table 没有固定大小,可以动态添加元素
  3. {} 是 table 构造式,用来创建一个 table
  4. # 长度操作符可以获取 table 的大小
  5. table 中的元素在未被初始化前都是 nil
  6. 可以将 table 中的元素赋值 nil 来进行删除
  7. 如果 table 中间部分的元素值为 nil 就说明这是一个有「空隙」的 table
  8. 有「空隙」的 table 要使用 table.maxn() 来返回这个函数的最大正索引数
  9. table 可以用来表示模块、包、对象
  10. table 中的索引可以是任何值,除了 nil
  11. table 是匿名的
  12. 程序仅保留了对 table 的一个引用
  13. 一个仅有 table 的变量和 table 自身并没有关系
  14. a.x 等价于 a["x"] 是以字符串为索引的
  15. a[x] 是以变量 x 为索引的
a = {}for i = 1, 10 do    a[i] = i    print(a[i])endfor i = 1, #a do    print(a[i])endprint(a[10]) -- 10print(#a) -- 10a[10] = nilprint(#a) -- 9a[10000] = 666print(#a) -- 9print(table.maxn(a)) -- 10000a = {}b = {}c = a print(type(a == b)) -- falseprint(type(a == c)) -- truex = "y"a["x"] = 666a["y"] = 777print(a.x) --666print(a[x]) -- 777

function

  1. 第一类值
  2. 可以存储在变量中
  3. 可以作为函数的返回值或参数
  4. lua 可以调用自身编写的函数也可以调用 C 语言编写的函数
  5. lua 标准库中的函数都是用 C 语言编写的

userdata

  1. 由应用程序或 C 语言编写创建的新类型
  2. 没有太多的预定义操作
  3. 仅用来做赋值和条件测试

3. 表达式

定义

  1. 表达式用于表示值
  1. 在 lua 中,函数调用,函数定义,数字常量、字面字符串,变量,一元和二元操作符,table 构造式都是表达式

算数操作符

一元操作符

  1. - 负号

二元操作符

  1. +
  2. - 减号
  3. *
  4. /
  5. %
  6. ^
-- % 的技巧-- x % 1print(3.13 % 1) -- 得到小数部分-- x - x % 1print(3.14 - 3.14 % 1) -- 得到整数部分-- x - x % 0.1print(3.14 - 3.14 % 0.1) -- 得到整数部分 + 一位小数部分-- x - x % 0.01 以此类推,是整数部分 + 两位小数部分

关系操作符

  1. >
  2. <
  3. >=
  4. <=
  5. == 相等性判断
  6. ~= 不等性判断

逻辑操作符

  1. and 第一个操作数为假,返回第一个,否则返回第二个
  2. or 第一个操作数为真,返回第一个,否则返回第二个
  3. not 只会返回 true 或 false
-- 短路操作的使用技巧print(x = x or v) -- 初始化一个值,如果 x 为 nil 没有被初始化过,就赋值 v -- 等价于if not x then     x = vend-- 实现 C 语言中的三元操作符, a ? b : cprint((a and b) or c) -- b 必须为真,才可以这样操作-- 等价于if a == true then    return belseif a == false then    return cend-- 实现返回两个数中的较大值max = (x > y) and x or y -- 因为 lua 将数字视为「真」-- 等价于if x > y then    return xelse    return yend

字符串连接

  1. .. 字符串连接

优先级

1级优先

  1. ^

2级优先

  1. - 负号
  2. not
  3. #

3级优先

  1. *
  2. /
  3. %

4级优先

  1. +
  2. - 减号

5级优先

  1. .. 字符串连接

6级优先

  1. >
  2. <
  3. >=
  4. <=
  5. ==
  6. ~=

7级优先

  1. and

8级优先

  1. or

table 构造式

  1. lua 标准库中的函数对 table 的索引都是从 1 开始处理的

记录风格的 table

a = {x = 10, y = 20} -- 等价于 a.x = 10, a.y = 20

混合使用的 table

  1. 这种方式的 table 不能以负数和操作符作为索引
a = {    color = {"red", "green", "blue"}    width = 200,    height = 300}

链表

  1. 由一系列节点组成,节点就是元素
  2. 节点可以再运行时动态生成
  3. 每个节点包括两部分存储数据的数据域存储下一个地址节点的指针域
list = nilfor line in io.lines() do    list = {next = list, value = line}endlocal l = listwhile l do    print(l.value)    l = l.nextend

指定索引的 table

options = {["+"] = "add", ["-"] = "sub",     ["*"] = "mul", ["/"] = "div"}print(options["+"]) -- "add"

4. 语句

  1. 在 lua 中包括赋值,程序结构和过程调用
  2. 还有多重赋值和局部变量声明

赋值

  1. lua 支持多重赋值,即 a, b = 1, 2
  2. 会先计算等号右边所有元素的值,然后再赋值
  3. 如果右边的值少于左边变量,未被初始化的变量就置为 nil
  4. 如果左边变量少于右边的值,多余的值会被「抛弃」
  5. 可用来收集函数的多个返回值
  6. 初始化变量就是为每一个变量赋一个初始值
a, b = 1, 2x, y  = y, x -- 交换变量a, b = 1 -- a = 1, b = nila, b = 1, 2, 3 -- a = 1, b = 2, 3 被抛弃a, b = f() -- a 接收函数 f 的第一个返回值,b 接收第二个a, b, c = 0, 0, 0 -- 初始化赋值

局部变量与块

  1. 一个块就是程序结构的执行体,或函数的执行体
  2. 在块内声明的变量仅在块内生效,即作用域为声明它们的块
  3. 可显式声明一个块使用 do end 将要执行的内容包裹在一个块内

局部变量

  1. local 用来声明一个局部变量
  2. 局部变量仅在声明它的块内生效,在块的外部无效
  3. 如:在循环内部声明在的变量在循环外部则无法使用
a = 3b = 0if a then    local a = 5    b = a -- 将 then 块内的局部变量 a ,保存到全局变量 b 中    print(a)endprint(a) -- 3print(b) -- 5do    -- code blockend

尽量使用局部变量

  1. 使用局部变量要比全局变量要快
  2. 避免污染全局环境
  3. 局部变量仅在声明它的块中有效,即在块外这个变量就被释放掉了
  4. lua 将局部变量声明当作语句处理,即可以在任何支持书写语句的地方书写局部变量声明
  5. 声明可以包含初始化赋值

程序结构

  1. 程序结构中的条件表达式可以是任何值

条件结构

  1. if
  2. elseif
  3. else
if 条件表达式 then      -- 符合条件表达式执行endif 条件表达式1 then     -- 符合条件表达式 1 执行    elseif 条件表达式2 then     -- 符合条件表达式 2 执行endif 条件表达式 then      -- 条件表达式为真时执行else      -- 条件表达式为假是执行end

循环结构

  1. for
  2. while 条件表达式为时退出
  3. repeat ... until 条件表达式为时推出,条件测试是在循环体之后做的,因此循环体至少会执行一次
  4. 在循环体内声明的局部变量的作用域包含了条件测试
  5. 循环的三个表达式是在循环开始前一次性求值的
  6. 控制变量会被自动声明为 for 块中的局部变量,即作用域为 for 块,在循环结束后不可见
  7. 不要在循环过程中修改控制变量的值
  8. 可以使用 break 或 return 在循环正常结束前提前结束它
for exp1, exp2, exp3 do    endwhile 条件表达式 do    endrepeat     until 条件表达式a = 20repeat    local a = 0    print(a)until a == 0 -- 可访问在 repeat 块内声明的 a, 而不是全局变量 a 
数值型 for
for i = 10, 0, -1 do    print(i)end
泛型 for
  1. ipairs() 用来遍历数组
  2. i 每次循环时都会赋予一个新的索引值,v 则是索引值所对应的元素
a = {1, 2, 3, 4, 5, 6}for i,v in ipairs(a) do     print(i)    print(v)endfor i,v in pairs(a) do    print(i)    print(v)end
两种 for 的共同点
  1. 循环变量都是循环体的局部变量
  2. 不应该对循环遍历进行赋值
days = {"第一天", "第二天", "第三天"}revdays = {}for i, v in ipairs(days) do    revdays[v] = i -- 逆向数组,将数组索引和数组元素调换,可获取数组元素的位置endprint(revdays["第二天"]) -- 获取第二天所在位置​

break 和 return

  1. break 用于结束一个循环,跳出内层循环后在外层循环中继续执行
  2. return 用于返回函数结果或简单的结束函数的执行
  3. 任何函数的结尾处实际都有一句隐式的 return
  4. 如果函数无返回值,就无需在结尾处加 return

两者的共同点

  1. 都是用作跳出当前块
  2. 都需要放在一个块的结尾处,即一个块的最后一条语句
  3. 因为 return 或 break 后的语句将无法执行到
  4. 可以用 do ... end 块包裹 return,用与调试,即调用函数但不执行函数内容的情况
a = 1if a then   print("hello")   break   print("world") -- 会报错endfor i = 1, 10 do    print(i)    if i > 3 then        break -- 只会打印 1 2 3 4 然后就跳出循环了    endend-- 调试function foo(...)    do        return     end    print("执行 foo 函数") -- 不会打印endfoo(1, 2 ,3)

5. 函数

  1. 函数是对语句和表达式进行抽象的主要机制

函数的两种用法

  1. 一是可以完成特定的任务,一句函数调用被视为一条语句
  2. 二是只用来计算并返回特定结果,视为一句表达式
print("hello") -- 用来完成打印任务,视为一条语句a = os.date() -- os.date() 用来返回日期,视为一句表达式

两种用法的共同点

  1. 都需要将所有参数放到一对圆括号中 ()
  2. 但当参数为字面字符串或 table 构造式的时候 ()可以省略
  3. 即使调用函数没有参数,也必须要有一对空的圆括号 ()
print "hello" -- helloprint {1, 2, 3} -- 1 2 3print(os.date) -- 当前日期

定义

  1. function 是创建函数的关键字
  2. function add add 是函数的名称
  3. function add(n) n 是函数的形式参数,简称为形参
  4. add(4) 4 是调用 add()函数时的实际参 ,简称为实参
  5. 实参多余形参,多余的实参被「抛弃」
  6. 形参多余实参,多余的形参被置为nil
function foo(a, b)    return a or bendfoo(1) -- a = 1, b = nilfoo(1, 2) -- a = 1, b = 2foo(1, 2, 31) -- a = 1, b = 2, 多余的 31 被抛弃-- 面向对象式调用o.foo(o, x)o:foo(x) -- 与上面的效果一样,: 冒号操作符,隐式的将 o 作为第一个参数

多重返回值

  1. lua 中的函数允许返回多个结果
  2. 用逗号分隔所需要返回的所有参数
string.find("you are cool", "are") -- 5 7 返回找到的字符串的开头位置和结尾位置-- 查找数组中的最大元素,并返回这个元素的所在位置function maximum(a)    local val = 1    local max = a[val]    for i,v in ipairs(a) do        if max < a[i] then            max = a[i]            val = i        end    end    return max, valenda = {1, 2, 55, 22, 29, 4}maximum(a)

不同情况下的返回值

  1. 如果将函数作为单独的语句执行,lua 会丢弃所有的返回值
  2. 如果将函数作为表达式的一部分调用,只保留函数的第一个返回值
  3. 只有当函数是一系列表达式中的最后一个元素(或只有一个元素的时候),才会获取所有的返回值

一系列表达式的4种情况

多重赋值
  1. 如果一个函数调用是最后(或仅有)的一个表达式,lua 会保留尽可能多的返回值,用来匹配赋值的变量
  2. 如果一个函数没有返回值或没有返回足够多的返回值,那么 lua 会用 nil 来补充缺失的值
  3. 如果一个函数调用不是一系列表达式中的最后一个元素,就只能返回一个值
function foo() endfunction foo1() return "a" endfunction foo2() return "a", "b" end​-- 第一种情况,最后(或仅有)的一个表达式x, y = foo1() -- x = a, y = b-- 第二种情况,没有返回值x = foo() -- nil-- 第二种情况,没有返回足够多的返回值x, y, z = foo1() -- x = a, y = b, z = nil-- 第三种情况,不是表达式中的最后一个元素x, y = foo2(), 10 -- x = a, y = 10
函数调用时传入的实参列表
  1. 如果一个函数调用作为另一个函数调用的最后一个(或仅有的)实参的时候,第一个函数的所有返回值都会作为实参传递给另一个函数
function foo() endfunction foo1() return "a" endfunction foo2() return "a", "b" end-- 第四种情况,作为 print 函数中的最后一个(或仅有的)实参print(foo()) -- nilprint(foo1()) -- "a"print(foo2()) -- "a" "b"print(foo1() .. "test") -- "atest"print(foo2() .. "test") -- "atest"
table 构造式
  1. table 构造式会完整接收一个函数调用的所有结果,即不会由任何数量方面的调整
  2. 但这种行为,只有当一个函数调用作为最后一个元素时才发生
  3. 其他位置上的函数调用总是只产生一个结果值
function foo() endfunction foo1() return "a" endfunction foo2() return "a", "b" end-- 函数调用是 table 中的最后一个元素a = {foo2()} -- a = {"a", "b"}a = {foo2(), 10} -- a = {"a", 10}
return 语句
  1. 将函数调用放入一对圆括号 () 中,使其只返回一个结果
  2. return 语句后面的内容不需要 () 圆括号
  3. 如果强行加上则会使一个多返回值的函数,强制其只返回一个 return(f())
function foo0() endfunction foo1() return "a" endfunction foo2() return "a", "b" endfunction foo(i)    if i == 0 then return foo0()         elseif i == 1 then return foo1()         elseif i == 2 then return foo2()     endendprint(foo(1)) -- aprint(foo(2)) -- a, bprint(foo(0)) -- 无返回值,在交互模式中会是一个空行​-- () 包裹print((foo(1)) -- aprint((foo(2)) -- aprint((foo(0)) -- nil ,应该是强制返回了一个未初始化的值,因为 foo0() 没有返回值

unpack 函数

  1. 接收一个数组作为参数
  2. 并从下标 1 开始返回该数组的所有元素
  3. 这个预定义函数由 C 语言编写
print(unpack{10, 20, 30}) -- 10 20 30a, b = unpack{10, 20, 30}  -- a = 10, b = 20
  1. 用于泛型调用
  2. 泛型调用就是可以以任何实参来调用任何函数
-- 调用任意函数 f, 而所有的参数都在数组 a 中-- unpack 将返回 a 中的所有值,这些值作为 f 的实参f(unpack(a)) f = string.finda = {"hello", "ll"}f(unpack(a)) -- 3 4 等效于 string.find("hello", "ll")

用 lua 递归实现 unpack

function unpack(t, i)    i = i or 1    if t[i] then        return t[i], unpack(t, i + 1)    endend

变长参数

  1. lua 中的函数可以接收不同数量的实参
  2. 当这个函数被调用时,它的所有参数都会被收集到一起
  3. 这部分收集起来的实参称为这个函数的「变长参数」
  4. ... 三个点表示该函数接收不同数量的实参
  5. 一个函数要访问它的变长参数时,需要用 ... 三个点,此时 ... 三个点是作为一个表达式使用的
  6. 表达式 ... 三个点的行为类似一个具有多重返回值的函数,它返回的是当前函数的所有变长参数
  7. 具有变长参数的函数也可以拥有任意数量的固定参数
  8. 但固定参数一定要在变长参数之前
  9. 当变长参数中包含 nil ,则需要用 select 访问变长参数
  10. 调用 select 时,必须传入一个固定参数 selector (选择开关) 和一系列变长参数
  11. 如果 selector 为数字 n ,那么 select 返回它的第 n 个可变实参
  12. 否则,select 只能为字符串 "#" ,这样 select 会返回变长参数的总数,包括 nil
-- 返回所有参数的和function add(...)    local s = 0    for i, v in ipairs{...} do -- 表达式{...}表示一个由变长参数构成的数组        s = s + v    end    return sendprint(add(3, 4, 5, 100)) -- 115​-- 调试技巧 ,类似与直接调用函数 foo ,但在调用 foo 前先调用 print 打印其所有的实参function foo1(...)    print("calling foo:", ...)    return foo(...)end​​-- 获取函数的实参列表function foo(a, b, c) endfunction foo(...)        local a, b, c = ...end-- 格式化文本 string.format ,输出文本 io.write-- 固定参数一定要在变长参数之前function fwrite(fmt, ...)    return io.write(string.format(fmt, ...))endfwrite() -- fmt = nilfwrite("a") -- fmt = a fwrite("%d%d", 4, 5) -- fmt = "%d%d" , 变长参数  = 4, 5​for i = 1, select('#', ...) do    local arg = select('#', ...)    end

具名参数

  1. lua 中的参数传递机制是具有 「位置性」的
  2. 就是说在调用一个函数时,实参是通过它在参数表中的位置与形参匹配起来的
  3. 第一个实参的值与第一个形参相匹配,依此类推
  4. 定义:通过名称来指定实参
  5. 可将所有的实参组织到一个 table 中,并将这个 table 作为唯一的实参传给函数
  6. lua 中特殊的函数调用语法,当实参只有一个 table 构造式时,函数调用中的圆括号 () 是可有可无的
os.rename  -- 文件改名,希望达到的效果 os.rename(old = "temp.lua", new = "temp1.lua")-- lua 不支持注释的写法rename = {old = "temp.lua", new = "temp1.lua"}function rename (arg)    return os.rename(arg.old, arg.new)end​x = Window{x = 0, y = 0, width = 300, height = 200, title = "Lua", background = "blue", border = "true"}​-- Window 函数根据要求检查必填参数,或为某些函数添加默认值-- 假设 _Window 是真正用于创建新窗口的函数,要求所有参数以正确次序传入function Window(options)    if type(options.title) ~= "string" then        error("no title")    elseif type(options.width) ~= "number" then        error("no width")    elseif type(options.height) ~= "height" then        error("no height")    end    _Window(options.title,        options.x or 0 -- 默认值        options.y or 0 -- 默认值        options.width, options.height,        options.background or "white" -- 默认值        options.border -- 默认值为 false(nil)    )end    

因为,目前只学到第五章函数篇,所以只有前五章的复习汇总,很基础,也很重要,并且我也把出现关键字和字母的地方加上了 code 块方便大家阅读,在此祝愿大家可以做什么事都能够踏踏实实地打好地基。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/434100.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

集群服务负载均衡------LVS

个人的理解&#xff0c;以一种通俗易懂的方式讲述出来&#xff0c;如果有哪些地方说的不正确的话&#xff0c;希望大家留言指出来。笔者会非是常的感谢&#xff01; Cluster服务器集群&#xff0c;直接理解为一些单一的服务器的集合通过某种方式组合起来&#xff0c;为客户端提…

tomcat jsp导入java_[导入]Tomcat JSP Web 开发中的乱码问题小姐

1. 静态页面的乱码问题文件的编码和浏览器要显示的编码不一致。1) 检查文件原始的编码, 可以用记事本打开, 然后选择另存为来看;2) 给当前页面加入一个指令来建议浏览器用指定的编码来显示文件字符内容.3) 如果系统是英文XP,没装东亚字符集支持, 也会显示乱码.2. JSP 页面的乱码…

四大开源分布式存储_ipfs分布式存储行业面临着四大主要风险,你知道是哪些吗?...

为了响应国家号召、推动分布式存储技术落地、防御行业风险&#xff0c;中国分布式存储产业联盟启动&#xff0c;全国从事IPFS以及分布式存储从业者对行业风险及联盟成立的必要性达成了高度共识&#xff0c;目前有36家以上的IPFS分布式存储行业企业填写了联盟申请表。几位国内知…

pjsua帮助手册(中文)

原文地址 : http://www.pjsip.org/pjsua.htm 介绍 PJSUA是一个开源的命令行SIP用户代理&#xff08;软电话&#xff09;&#xff0c;用PJSIP协议&#xff0c;PJNATH&#xff0c;和PJMEDIA实现。 它虽然只有很简单的命令行界面&#xff0c;但是功能齐全。 SIP功能&#xff1a; 多…

js date转成 时间字符串_秋招快要开始了,前端笔试中的坑位-JS隐式转换问题

我们在写笔试题的时候&#xff0c;经常碰到涉及隐式转换的题目&#xff0c;例如"1" 2 obj 1 [] ![] [null] false 和 叫做严格运算符&#xff0c;对象类型指向地址相同或原始类型&#xff08; 数值、字符串、布尔值&#xff09;值相同&#xff1b;叫做相等运算…

Java中快速处理集合_简洁又快速地处理集合——Java8 Stream(上)

作者&#xff1a;Howie_Y&#xff0c;系原创投稿主页&#xff1a;www.jianshu.com/u/79638e5f0743Java 8 发布至今也已经好几年过去&#xff0c;如今 Java 也已经向 11 迈去&#xff0c;但是 Java 8 作出的改变可以说是革命性的&#xff0c;影响足够深远&#xff0c;学习 Java …

eclipse编译java项目class文件_动态编译 Java 代码以及生成 Jar 文件

导读&#xff1a; 最近在看 Flink 源码的时候发现到一段实用的代码&#xff0c;该代码实现了 java 动态编译以及生成 jar 文件。将其进行改进后可以应用到我们的平台上&#xff0c;实现在平台页面上编写 java 代码语句&#xff0c;提交后由后台进行编译和打成 Jar 包再上传到指…

Dx11DemoBase 基类(三) 实例应用 【已实现】【附带源码】

现在我已经到哪了? 读书时&#xff0c;尤其是技术知识书籍&#xff0c; 我一般会担忧自己是否陷得太深&#xff0c; 细节关注得太多&#xff0c; 而忘了整体的过程&#xff1b; 一直以来对Direct3D 很畏惧&#xff0c; 因为太多函数和细节&#xff1b;现在我必须暂缓下&#x…

修改 decimal 默认值为0.00 sql_被经理邀请去“爬山”,只是因为我写错了一条SQL语句?...

作者&#xff1a;isysc1链接&#xff1a;https://juejin.im/post/5f06a2156fb9a07e5f5180df来源&#xff1a;掘金前戏SQL 写的妙&#xff0c;涨薪呱呱叫&#xff01;新来的实习生小杨写了一条 SQL 语句SELECT wx_id from user WHERE wx_id 2当小杨迫不及待准备下班回家的时候&…

JS中关于clientWidth、offsetWidth、scrollWidth

网页可见区域宽&#xff1a; document.body.clientWidth;网页可见区域高&#xff1a; document.body.clientHeight;网页可见区域宽&#xff1a; document.body.offsetWidth (包括边线的宽);网页可见区域高&#xff1a; document.body.offsetHeight (包括边线的宽);网页正文全…

shell 执行失败重试_Uipath 机器人总是运行失败怎么办?

要知道为什么RPA机器人容易失败&#xff0c;首先了解下它和常规的应用系统有哪些区别。常规应用系统&#xff0c;就像程序员自己创造了一个世界、一个域&#xff0c;在这个世界里创造它的人就是主宰。出现BUG的风险是相对可控的&#xff0c;顶多是功能用不了。而RPA项目&#x…

c mysql安装教程视频_MySQL安装教程 - Windows安装MySQL教程 - 小白式安装MySQL教程 - 青衫慧博客...

版权声明本文转发自旧站点萧瑟云日志&#xff0c;近期考虑准备将旧站进行关闭(没有精力维护)&#xff0c;部分文章将会迁移至本站。文章发表于&#xff1a;2017-10-28 12:32:03前言上次给大家带来了SQL Server的小白式安装教程&#xff0c;这次再次带来一个MySQL的小白式安装教…

PJSIP UA分析(1)--PJSUA主函数

1 intmain(intargc, char*argv[])2 {3 do{4 app_restart PJ_FALSE; //PJ_FALSE是一个宏&#xff0c;一旦用户调用pjsua可执行文件进入该循环&#xff0c;那么默认只执行一次退出5 //如果需要再次循环&#xff0c;那么在下面函数中…

锁定表头和固定列(Fixed table head and columns)

前段时间需要这个功能&#xff0c;但是找了很多都不能完美的实现&#xff0c;不是只能锁定表头&#xff0c;就是浏览器兼容问题什么的&#xff0c;在此就自己做了一个锁定表头和列的js方法&#xff0c;依赖于JQuery。 因为方法很简单&#xff0c;就未封装成插件的形式&#xff…

游戏详细设计说明书_宜家的说明书设计脑洞太大了!

平常我们看到的说明书是像这样纯文字解说的或者是规范的文字配图这些说明书一般都是注重文字的上表达而大家熟悉的家居品牌宜家将说明书创意玩出了新境界&#xff01;↓↓↓这不&#xff0c;最近由于全球疫情严峻期间宜家的全新说明书手册搜罗了各种纸上游戏意为帮助大家打发无…

centos删除php_centos如何卸载php

查看php版本php -v查看php相关软件包#rpm -qa|grep php(视频教程推荐&#xff1a;linux视频教程)提示如下&#xff1a;#php-pdo-5.1.6-27.el5_5.3#php-mysql-5.1.6-27.el5_5.3#php-xml-5.1.6-27.el5_5.3#php-cli-5.1.6-27.el5_5.3#php-common-5.1.6-27.el5_5.3#php-gd-5.1.6-27…

cgblib 代理接口原理_Java开发者你还不知道?告诉你Dubbo 的底层原理,面试不再怕...

前言平常我们在构建分布式系统的时候&#xff0c;一般都是基于 Dubbo 技术栈或者是SpringCloud 技术栈来做。早期其实最先比较流行的是Dubbo&#xff0c;我记得我们当时有个部分的老大就是用的是Dubbo 来构建的一个系统&#xff0c;到后面才出来的 SpringCloud&#xff0c;由于…

包含对流环热,热流边界,等温边界的稳态热传导方程的FEM求解。

以下面的问题为例&#xff1a;对于如图所示的平面传热问题&#xff0c; 若上端有给定的热流-2W/m2&#xff0c;即从下往上传输热量&#xff0c;结构下端有确定的温度100&#xff0c;周围介质温度为20&#xff0c;在两侧有换热&#xff0c;换热系数为α100W/㎡/K&#xff0c;热导…

python生成动态二维码实例_python生成动态个性二维码(示例代码)

1 安装工具 2 生成普通二维码 3 带图片的二维码 4 动态 GIF 二维码 5 在Python程序中使用 一、安装 首先在python环境下运行&#xff0c; 打开cmd进入python27 进入scripts 然后在scripts输入命令&#xff1a;pip install myqr二、 生成普通二维码 安装了 myqr 之后&#xff0c…

matlab武汉理工大学数值分析线性函数拟合实验_「首席架构师推荐」数值计算库精选...

这是一个著名的数值库列表&#xff0c;这些库用于软件开发中执行数值计算。它不是一个完整的列表&#xff0c;而是一个包含Wikipedia上文章的数字库列表&#xff0c;很少有例外。典型库的选择取决于一系列不同的需求&#xff0c;例如:期望的特性(例如:大维线性代数、并行计算、…