前言:本文代码最终封装为godking库的f()函数:
函数名称:f (__,true/*包含全局变量*/,/*开始调用级*/)
函数说明:用对应的变量值,替换字符串中的“{变量名}”
参数1:包含变量名的字符串
参数2:是否包含全局变量(默认true)。否则仅限var声明的局部变量
参数3:从该调用级开始向上查找直到根级(1)范围内的局部变量。默认为调用f()函数的代码所在的层级。
返回值:处理后的结果文本
类似于python中的f"abc{var}def"表达式,如:
var num = 123;
var s = f("abcd{num}efgh")
则 s 的值为:abcd123efgh
表达式支持四种方式:
1:仅变量名,如: { i } 或 { namespace.i } ,优先顺序为:名字空间变量、局部变量、全局变量,找不到则返回 eval 进行计算的结果。
注意:如果变量名中含有点【.】如“a.b”,则视为名字空间变量,将跳过查找变量的步骤,直接用 eval 进行计算。
2:用变量名加 :% 表示格式化该变量,如 { i:%02f } 或省略% { i:02f },返回格式化结果。
3:用变量名加 := 表示包含该变量的公式,如 { i:=i+1 },返回公式计算结果。
注意:
a、全局变量可省略 := 符号,直接使用公式,如 { i+1 }(原理:先找名称为“i+1”的变量(先局部变量、后全局变量),因为找不到名称为 i+1 的变量,所以最后用 eval 进行计算并返回计算结果)。但建议直接使用纯公式 { =i+1 } 计算全局变量公式,这样可以跳过查找变量的步骤,直接取 eval 计算结果。
b、局部变量则必须要用 := 指定公式,如 { i:=i+1 }
4:用 = 开头,表示不查找变量值,纯公式计算,直接返回 eval 结果。如: { =(1+2)*3 }
注意:公式里面可包含全局变量名或名字空间变量名,不支持局部变量。
虽然省略 “ = ” 结果也一样,但使用 “ = ” 减少了“查找变量”的过程,直接返回 eval 结果,效率更高。
一:引言
假设已经声明好许多变量,如下:
// 各种变量(常量)
console.name = "张三" //成员变量
::age = 18 //全局常量
..sex = "男" //全局变量
var score = 90 //局部变量
var t = { //数组
结果 = "优秀";
评语 = "很好,nice,继续努力!";
}
_OK = "惊不惊喜?" //全局常量
如果我们要将他整合到一串文本中,比如sql语句之类的,通常做法是:
var s = ..string.format('姓名:%s\n年龄:%s\n性别:%s\n成绩:%s\n结果:%s\n备注:%s'
,console.name,age,sex,score,..table.tostring(t),_OK);
执行结果:
或:
var s = ..string.format(
`姓名:%s
年龄:%s
性别:%s
成绩:%s
结果:%s
备注:%s`,
console.name,age,sex,score,..table.tostring(t),_OK);
执行结果:
二、基本解决方案:
貌似这样已经非常方便了。
但是python有个更加方便,最重要的是,非常直观的格式化字符串的方法:f
f-string
一种格式化字符串的方法,使用以
f
开头的字符串,称之为f-string
,它和普通字符串不同之处在于,字符串如果包含{xxx}
,就会以对应的变量替换:>>> r = 2.5 >>> s = 3.14 * r ** 2 >>> print(f'The area of a circle with radius {r} is {s:.2f}') The area of a circle with radius 2.5 is 19.62
上述代码中,
{r}
被变量r
的值替换,{s:.2f}
被变量s
的值替换,并且:
后面的.2f
指定了格式化参数(即保留两位小数),因此,{s:.2f}
的替换结果是19.62
。
将变量名称放在它应该在的最合适的位置, 让易读性变得非常强。
那么,用aardio可以模仿这种语法么?
《 aardio调试库解决局部变量的有趣问题(一)_aardio笔记的博客-优快云博客_aardio》
一文启发(在此表示感谢),我们模仿f-string,造一个 f() 函数,实现这个功能,来看看下面这个语句:
重点来了:
是不是非常接近了!!
自己构造一个语句试试:
var s = f('姓名:{console.name}\n年龄:{age}\n性别:{sex}\n成绩:{score}\n结果:{t}\n备注:{_OK}')
想想执行结果是啥?看看:
或:
var s = f(`
姓名:{console.name}
年龄:{age}
性别:{sex}
成绩:{score}
结果:{t}
备注:{_OK}
`)
执行结果:
三、更多用法:
是不是看着很舒服?变量名称所在的位置,一目了然,阅读起来非常舒服。
再看更多详细用法:
1、格式化文本:
import console;
var t = "ABCD"
var num = 456
var num2 = 12345678
var s="({t:10s})({num:10.2f})({num2:X})"
import godking
console.dump(f(s))
console.pause(true);
执行结果:
2、指定函数调用级:
import console;
import godking
var s = "当前取到的变量的调用级为:{t}"
var t = "第一级"
var test = function(){
var t = "第二级"
import debug
var level=debug.callcount();
//从本级向上找,直到根级1级。
console.dump("从调用代码级("++level++")开始:",f(s));
console.dump("从调用代码级("++level++")开始:",f(s,,level));
//从上一级向上找,直到根级1级。
console.dump("从调用代码的上一级(1)开始:",f(s,,level-1));
//从上上一级向上找,直到根级1级。
console.dump("从调用代码的上上一级(0)开始:",f(s,,level-2));
}
test();
console.pause(true);
执行结果:
从调用代码级(2)开始: 当前取到的变量的调用级为:第二级
从调用代码级(2)开始: 当前取到的变量的调用级为:第二级
从调用代码的上一级(1)开始: 当前取到的变量的调用级为:第一级
从调用代码的上上一级(0)开始: 当前取到的变量的调用级为:请按任意键继续 ...
3、不包括全局变量:
import console;
t = "ABCD";
::num = 1111;
..num2 = 456
var 局部变量 = "我是局部变量"
var s="({t:10s})({num:10.2f})({num2:X})({局部变量})"
import godking
console.dump("包含全局变量:",f(s));
console.dump("不包含全局变量:",f(s,false));
console.pause(true);
执行结果:
4、直接用公式:
import console;
import godking
// 如果变量名以=开头,则执行eval操作,将eval结果作为变量值返回。
// 当然,=也可以省略,结果虽然一样,但中间多了“查找变量”的过程,理论上来说,效率变低。
var s="({=3+6*8})({=console.color.red})({=..math.pi})"
console.dump(f(s));
console.pause(true);
执行结果:
(51)(12)(3.1415926535898)
请按任意键继续 ...
5、一个无聊的测试:
import console;
var s="({s})"
import godking
for(i=1;5;1){
s = f(s)
}
console.dump(s)
console.pause(true);
执行结果:
四、库下载地址:
f() 函数代码封装于光庆扩展函数库中,请此处下载:
aardio资源下载 ↔ _.rar ,解压缩后放到\lib\godking目录中。