//table 表对象 namespace builtin; self.table = global.table; namespace table{ find = function(t,f){ if(type(f)==="function"){ for(k,v in t) if( f( v,k,t ) ) return k,v; } for(k,v in t){ if( v === f ) return k; } }; findAll = function(t,f){ var a = {} if(type(f)==="function")for(k,v in t){ if( f( v,k,t ) ) push(a,k) } else for(k,v in t){ if( v === f ) push(a,k) } return a; }; indexOf = function(a,v,from){ if(from===null) from = 1; if(from<0) from = #a + from + 1; for(i=from;#a) { if( a[i] === v ) return i; } }; lastIndexOf = function(a,v,from){ if(from===null) from = 1; if(from<0) from = #a + from + 1; for(i=#a;from;-1) { if( a[i] === v ) return i; } }; shift = function(t,n=1){ if(!t) error("无效参数@1",2) if(#t) return unpack( splice(t,1,n) ); }; unshift = function(t,...){ if(!t) error("无效参数@1",2) if( #t) splice(t,1,0,...); else push(t,...); return #t; }; unpackArgs = function(t){ var b,e = range(t) return unpack( t,1,e); }; spliceArgs = function(t,i,l,a,b,e){ var b2,e2 = range(a); return splice(t,i,l,unpack(a,b:b2,e:e2)); }; eachArgs = function(t){ var a,b = range(t);a=0; return function(){ if( a < b ){ a++; return a,t[a] } } ; }; clear = function(t){ if(#t) splice(t,1,#t); for(k,v in t) t[k] = null; }; assignDeep = function(a,b,...){ if(a===null) a = {}; for(k,v in b) if( ( a[[k]] === null ) || (type(k)!="string") || (k[1]!='_'#) ) { if( type(v) == "table" ){ if( (type(a[k]) == "table" ) && ((a[k])!=v) ) assignDeep( a[k],v ) else a[k] = clone(v); } else a[k] = v; } if(!...) return a; return assignDeep(a,...); }; assign = function(a,b,...){ if(a===null) a = {}; for(k,v in b) if( ( a[[k]] === null ) || (type(k)!="string") || (k[1]!='_'#) ) a[k] = v; if(!...) return a; return assign(a,...); }; mix = function(a,b,...){ if(a===null) a = {}; for(k,v in b) if( a[[k]] === null){ a[k] = v}; if(!...) return a; return mix(a,...); }; array = function(l,v,...){ var r = [] var t = type(v); var t1 = type(l); if( t1 == "function" || t1 == "class" ){ while( var i; i = [l(v,...)]; i[1]!==null) { push( r,i); } } elseif( t1 == "table" ){ append(r,l); if( t === "number" ){ r@ = { length = v == -1? rget(2,range(l)):v }; } } elseif( t == "function" || t == "class" ) { if( l ){ for(i=1;l) r[i]= v(...); } else { while(var i;i = v(...);i!==null) { push( r,i); } } } elseif( t == "table" ) for(i=1;l) r[i]= append([],v); else { if( (... !== null) && ( t == "number") ) { for(i=1;l ) r[i]=array(v,...); } elseif(v!==null) { for(i=1;l) r[i]= v; } } return r; }; flat = function(a,d = 1) { return d ? reduce(a,lambda(r,v) append(r,isArray(v) ? flat(v,d-1):{v}),{}) : a }; get = function(k,t){ if(!t){ t = ..global; } var p,m = ..string.match(k,"\.*(.*)(%\[\])$"); if( m ) m = #m>2 ? eval(..string.slice(m,2,-2)) : #t; else p,m = ..string.match(k,"\.*(.+)\.([^.]+)$"); if( m!==null ){ if(#p){ t = get(p,t);} if(t){ return t[m],t; } } else{ return t[k],t }; }; var setByPath; setByPath = function(k,v,t,n=0){ var p,m = ..string.match(k,"\.*(.*)(%\[\])$"); if( m ){ if(#p)t = setByPath(p,,t,n+1); k = #m>2 ? eval(..string.slice(m,2,-2)) : #t+1; } else{ p,m = ..string.match(k,"\.*(.+)\.([^.]+)$"); if( m!==null ){ t = setByPath(p,,t,n+1); k = m } } if( n ){ if( t[k]===null ) t[k] = (v===null) ? {} : v ; } else{ t[k] = v; } return t[k]; }; set = function(k,v,t){ if(!t){ t = ..global } return setByPath(k,v,t,0) }; self.namespace = function(ns){ if( call(loadcodex,,"namespace " + ns)) return eval(ns); }; define = function(t,...){ if(!t@)t@={} if(!t@._defined)t@._defined = {}; if(...)push(t@._defined,...); else {clear(t@._defined)} }; keys = function(t,f,n){ var d = {}; var keys = {}; var pred = {}; if(n){ var k; for(i=1;#n){ k = n[i] ; d[k] = t[k]; if( d[k] !== null ){ push(pred,k); } } } var mkeys = t@[["_keys"]] if( mkeys ){ if( type(mkeys) == type.function ) mkeys = invoke(mkeys,t); for i,k in mkeys if( ( d[k] === null ) && type(k)=="string" ) { push(keys, k); d[k] = true; } } else{ for k in t if( ( d[k] === null ) && type(k)=="string" && k != "_struct") { push(keys, k); d[k] = true; } } sort(keys, f); if( n ){ if(#keys){ append(pred,keys) } keys=pred; } var defined = t@[["_defined"]] if( defined ){ if( type(defined) == type.function ) defined = invoke(defined,t); for(i,k in defined){ if( d[k] === null ) { push(keys, k); d[k] = true; }; } } return keys; }; eachName = function(t,f,n){ var keys = keys(t,f,n); var i,k; return function () { i,k = next(keys,i) if(k) return k, t[k]; } }; eachValue = function(t,f){ var keys = {} for(k,v in t) push(keys,k); sort(keys,function(b){ if( f ) return invoke(f,t,t[owner],t[b]); return t[owner] < t[b]; }); var i,k; return function () { i,k = next(keys,i) if(k!==null) return k, t[k]; } }; len = function(a){ var lm,la = a@[["length"]],#a; if( type(lm) == "function") lm = invoke(lm,a); //length 元方法允许返回 null if( type(lm) == "number") return ..math.max(lm,la); var lf = a.length || a.Length; if( lf && (type(lf)=="number")) return ..math.max(lf,la); return la; }; eachIndex = function(t){ var len = len(t); var startIndex = t@[["_startIndex"]]; if( startIndex === null ) startIndex = 1; len = len + startIndex - 1; var v; return function(){ if(startIndex<=len){ startIndex++; return startIndex-1,t[startIndex-1]; } } }; count = function(t){ var i = 0; for(k,v in t){i++}; return i; }; shuffle = function(t){ var r,i = ..math.random; for(c=#t;2;-1){ i = r(1,c); t[i],t[c] = t[c],t[i]; } return t; }; invert = function(t){ var t2 = {}; for(k,v in t) t2[v]=k; return t2; }; map = function(t,f){ var r = {}; for(k,v in t) { v = f(v,k,r);if(v!==null)r[k]=v;} return r; }; mapDeep = function(t,f){ var r = {}; for(k,v in t) r[k] = (type(v) == "table") ? mapDeep(v,f) : f(v,k,r); return r; }; filter = function(a,f){ var r = {} for(i=1;#a) if( f( a[i],i ) ) push(r,a[i]); return r; }; every = function(t,f){ for(k,v in t) if( !f( v,k ) ) return; return true; }; some = function(t,f){ for(k,v in t) if( f( v,k ) ) return true; }; removeByValue = function(t,v,m){ var len,_ = #t; if( v === null ) { _,len = range(t); if(m === null) m = true; if(t@[["length"]]){t@[["length"]]=null;} } if(!m) { for(i=1;#t;1)if(t[i]===v){remove(t,i);return i;} } else { for(i=len;1;-1) if(t[i]===v) remove(t,i); } }; self.type = function(v){ if( type(v) != "table" ) return; if( isArray(v) ) return "array"; var m = v@; if(m){ var t = m[["_type"]]; if( t == "array" ) return "array"; if( t == "object" ) return "object"; var mlen = m[["length"]]; if( mlen !== null ){ if(type(mlen)=="function"){ mlen = mlen();//length 元方法可返回 null 以声明不期望被识别为数组 if(mlen !== null) return "array"; else return t || "object"; } return "array"; } if( m[["_keys"]] || m[["_defined"]] ) return "object"; } if(v[["_struct"]]) return "object"; if( ( type(v.length) == "number" ) ) return "array"; if( ( type(v.Length) == "number" ) ) return "array"; if( #v ) return "array"; return "object"; }; gc = function(o,gc){ var gd = ..raw.buffer(1); gd@ = { _gc = function(){ call( type(gc)=="string"?o[gc]:gc,o);} } o[["_gc"]] = gd; return o; }; gcOnly = function(func){ var d; d = ..gcdata(_gc = function(){d = false; }); return function(){ if(d!==false) return; invoke(func,owner); } }; create = function(p,...){ return assign( p ? { @{_get=p} } : {},...); }; cache = function(kv,get){ if(kv && (type(kv)!=="string")) kv,get = get,kv; return {@{_weak=kv:"kv";_get=get?function(k){ var v = get(k);owner[[k]]=v;return v;} }} }; getCall = function(t,k){ return t[[k]] || invoke(t@._get,t,k,true); }; var strip; var __nvType = {"function":1,"class":1,"fiber":1,"cdata":1} strip = function(t,ref) { if(ref[t]) return {}; ref[t] = true; var json = t@[["_json"]] if(json && json!=parseValue) { var j,s = invoke(json,t) if(!s && (j!==null) && (j!==t))return j; } var vt; if( self.type(t) == "array" ){ var r = [] for k,v in eachIndex(t){ vt = type(v); if(vt=="table") v = strip(v,ref) elseif(__nvType[vt]) continue; push(r,v); } return r; }; var r = {} for k,v in eachName(t){ vt = type(v); if(vt=="table") v = strip(v,ref) elseif(__nvType[vt]) continue; r[k] = v; } return r; } parseValue = function(v){ if( type(v) != "table" ) return v ; return strip(v,{}); } mixin = assign;//@Deprecated mixr = assignDeep;//@Deprecated mapr = mapDeep;//@Deprecated delegate = create;//@Deprecated add_gc = gc;//@Deprecated each = eachName;//@Deprecated getByNamespace = get;//@Deprecated setByNamespace = set;//@Deprecated } /**intellisense(table) cache() = 创建并返回弱引用缓存表,\n弱引用指的是加入表中的键或值不会增加引用计数,\n不会阻止对象被回收,\n返回的弱引用表适合用于缓存对象 cache(.(getter) = 创建并返回弱引用缓存表,\n可选用参数 @getter 指定读取值函数,\n该函数的参数为当前读取的键,函数应返回对应的值,\n在返回读取值以前,该值会被临时存入缓存表 cache(.(kv,getter) = 创建并返回弱引用缓存表,\n可选用参数 @kv 指定弱引用类型,\n参数@1为字符串 "k" 时仅弱引用键,为 "v" 仅弱引用值,\n不指定刚默认为 "kv", 指弱引用键与值。\n可选用参数 @getter 指定读取值函数,\n该函数的参数为当前读取的键,函数应返回对应的值,\n在返回读取值以前,该值会被临时存入缓存表 type(__) = 用于检测参数指定的表对象的首选操作类型(preferred type)。\n如果参数 @1 不是表(table)则返回 `null`,否则返回字符串 `"array"` 或者 `"object"`\n\n返回 "array" 则表明表对象可作为伪数组(pseudo-array)\n使用 table.len ,table.eachIndex 等函数操作。\n\n函数检测顺序如下:\n1. 纯数组总是返回 "array"。\n2. _type 元属性如果明确指定了 "array" 或`"object" 则直接返回。\n3. length 元属性或元方法返回非 null 值则返回"array",如果指定了 length 元方法但调用元方法返回 null 值返回"object"。\n4. 指定了 _keys 或 _defined 等预定义名值对的元属性返回 "object"。\n5. 如果对象的 length 或 Length 字段用数值指定了数组长度则返回 "array"。\n6. 如果使用 `#` 操作符取对象的稠密数组元素个数返回非零值则返回 "array"。\n7. 以上都不符合时默认返回 "object" 。 isArrayLike(__) = 参数 @1 如果是类数组(array-like table)则返回 true,否则返回 false。\n`类数组`是指纯数组(pure-array)或包含稠密数组成员的`表`(用 `#` 操作符取到非零长度)。\n\n`类数组`可使用 `#` 操作符获取稠密数组成员的长度,可使用 \n`for(i=1;#arrayLike;1){ var v = arrayLike[i] }` 的方式遍历数组元素。 isArray(__) = 检测参数是否纯数组( pure-array ),。\n注意纯数组的数据类型也是表( pure-array table ),\n\n纯数组是起始索引为 1 的稠密数组,但也可以包含其他类型的键值对。\n可以使用以下方式创建纯数组:\n- 在代码中用 `[]` 构造纯数组。\n- 调用 table.array 构造纯数组。\n- 调用 com.SafeArray 函数构造纯数组。\n- 操作并创建新稠密数组的标准库函数通常返回纯数组。\n- 原生结构体的内存数组转换为 aardio 数组时返回纯数组。\n\n在 `[]`构造器内 `[]` 只能表示子数组,不能用于包含索引。 len(.(数组) = 获取纯数组、类数组、或伪数组(pseudo-array)的长度。\n\n获取长度步骤如下:\n1. 取 length 元属性的值( 如果是函数则先执行并取值 ),\n如果取到的值为数值,则在该值与 `#` 操作符获取的长度中取最大值返回。\n2. 取 length 或 Length 字段的值,\n如果取到的值为数值,则在该值与 `#` 操作符获取的长度中取最大值返回。\n3. 否则返回 `#` 操作符获取的稠密数组成员的长度。\n\nJSON.stringify 将调用此函数以支持定长数组。 define(.(表对象,->->->) = 预定义一个或多个键名\n即使对应键的值为 null,仍然在 eachName 迭代器中显示出来\n注意该迭代器的预定排序对null值无效,\n此函数在对象的元表的 _define 元属性添加键名,\n如果 _define 为数组或 null 则可重复调用此函数。\n如果 _define 已经定义为函数对象则会失败\n table.eachName,webs.json 等自动支持 _define 元属性 define(.(表对象) = 清空预定义键名 keys(.(表对象,排序函数,优先前排键名) = 获取表中的所有字符串类型的键名(不含 _struct),\n\n如果元表中定义了 _keys 元属性或元方法,则使用 _keys 获取全部键名数组取代对象实际的键名数组。\n\n如果元表中定义了 _defined 元属性或元方法法,则使用 _defined 获取允许值为 null 的键名。\n_keys 的作用是替换键名数组,而 _defined 的作是预定义部分键名(既使没有包含实际的键值)。\n\n可选指定键名排序函数,如果不指定则使用默认字典序排序,\n可选使用参数 @3 预定义优先排序在最前面的键名数组 eachIndex(数组) = @for i,v in table.eachIndex(__/*可用于遍历纯数组、类数组、伪数组等表对象的数组元素。\n按数组索引大小顺序遍历数组。\n支持使用表对象的 length 属性,_length 元方法确定数组的长度。\n支持表对象使用 _startIndex 元属性自定义下标。\n如果是普通的纯数组不需要用到这些功能。\n改用计数 for 循环会更快*/){ } eachName(表对象,排序函数,预定定前排键名) = @for k,v in ??.eachName(__/*使用表中的键排序并遍历所有键值对\n参数: @1表对象, @2排序函数, @3排序表\n调用table.keys获取排序后的键名,支持_keys,_defined元方法\n所有参数用法与table.keys相同*/){ } eachValue(表对象,排序值函数) = @for k,v in table.eachValue(__/*使用表中的值排序并遍历所有键值对,\n默认值最小的排在前面,可选在后面指定排序函数,\n排序函数的v,v2参数为正在比较的成员值,owner参数为表自身,\n如果要v排在前面返回true,请用<或>比较,不要用>=或<=\n省略排序值的函数则值小的排在前面*/,lambda(a,b) a > b ){\n \n} find( = 在表包含的所有键值对象搜索匹配的值,找到第一个值就返回对应的键。\n以值查键才需要调用此函数,以键查值请改用下标操作符直接检索,例如:\n`if( tabObject["keyName"] ) {} ` find(.(表,查找值) = 在表对象中以值查键。\n在表中搜索所有键值对,并使用恒等操作符匹配相等的值。\n找到第一值值就返回对应的键,找不到则返回 null find(.(表,回调函数) = 遍历表中所有的值,返回匹配成功的`键`,`值`(返回值有 2 个)。\n并调用参数 @2 指定的回调函数,直到回调函数返回 true 时返回匹配的`键`,`值`。\n回调函数参数为(当前值,当前键,表对象) findAll(.(表,查找值) = 在表包含的所有键值对象搜索匹配的值,返回这些值对应的`键`组成的数组。\n使用恒等操作符查找并匹配值(数据类型与值都必须完全相等,不会自动转换类型)。\n找不到返回空数组,可使用 `#` 操作符取数组长度判断查找结果。 findAll(.(表,回调函数) = 遍历表中所有的非函数值,\n并调用参数 @2 指定的回调函数,\n回调函数接收到的参数为(当前值,当前键,表对象)。\n回调函数返回 true 则`当前键`添加到 table.findAll 函数的返回值(数组)中。\ntable.findAl 的返回值为由表对象中所有匹配成功的`键`数组,无任何匹配值返回空数组。 lastIndexOf(.(表,查找值,开始索引) = 在数组中自后向前查找参数@2指定的值并返回对应的数组索引,\n开始索引省略时默认值为1,可用负数表示自尾部开始的倒计数索引值,\n无任何匹配值时返回null,有匹配值时返回大于或等于1的索引值 indexOf(.(表,查找值,开始索引) = 在数组中自前向后查找参数@2指定的值并返回对应的数组索引,,\n开始索引省略时默认值为1,可用负数表示自尾部开始的倒计数索引值,\n无任何匹配值时返回null,有匹配值时返回大于或等于1的索引值 array( = 创建纯数组( pure-array ),参数可以为空。\n纯数组的数据类型也是表( table ), 但主要用于创建与操作稠密数组。\n纯数组传入 table.isArray,table.isArrayLike 函数都会返回 true 。\n纯数组在使用 table.tostring 或 JSON.stringify 等序列化后总是使用 `[]` 包围数组成员。 array(.(任意个数组长度,默认值) = 可使用不定个数长度参数指定多维数组长度。例:\n `table.array(3,5,[] )` 。\n如果默认值是 table 对象使用浅拷贝方式复制数组成员为纯数组。 array(.(任意个数组长度,取值函数或类,任意个调用参数) = 可使用不定个数长度参数指定多维数组长度,\n最后一个参数可以是创建默认值的函数或类,并在后面指定调用参数 array(.(取值函数或类,任意个调用参数) = 如果参数 @1 是函数或类,\n这时候会循环调用参数 @1 直到函数或类返回 null 值。\n每次调用的所有返回值放到一个纯数组中,\n返回包含这些纯数组的纯数组。\n如果只想返回包含首个返回值的一维数组,\n请添加一个 null 参数,将参数 @1 移动到参数 @2 位置。\n\n参数 @1 可指定有状态的迭代器,不支持无状态的迭代器。 array(.( ,取值函数或类,任意个调用参数) = 如果参数@1为空,且参数 @2 是函数或类,\n则循环调用参数 @2 直到函数返回 null 值,\n每次取首个返回值放入一个纯数组,并返回该数组。\n\n参数 @2 不可使用无状态的迭代器。 array(.(源数组,最小长度) = 如果参数 @1 为表或数组,\n则获取所有数组成员并复制(浅拷贝)到新的纯数组中。\n返回纯数组,如果指定最小长度则使用 length 元属性声明最小长度。\n最小长度为 -1 时则自动获取最大数值索引作为最小长度。\nlength 仅对 JSON.stringify 等特定函数有效,跨线程传递数组时也会丢弃 length 元属性。 slice(.(数组,开始位置,结束位置) = 从指定位置截取并返回新数组,\n开始位置可选,默认为1\n结束位置可选,默认为数组长度,返回值包含结束位置元素,\n如果位置参数为负数,则自右侧反向计算 assignDeep( = 递归式混入表、支持递归混入嵌套的成员表。\n此函数使用深拷贝方式复制对象,但会丢弃对象的元表。 assignDeep(.(对象,任意多个混入对象->->->) = 将参数列表中后面的表对象深度混入前面的表对象,并返回合并后的表对象。\n实际上就是返回参数 @1 指定的表对象( 如果参数 @1 为空则默认创建新表作为合并的目标 )。\n\n在混合表对象时如果遇到已存在的键值,并且目标值与源值都是表对象,\n则继续使用 table.assignDeep 递归混入子表(合并子表而非替换已存在值),\n否则以深拷贝的方式复制键值到目标表内(这会替换已存在的键值)。\n\n此函数总是使用深拷贝,并支持递归混合子表,要避免用于复制在子元素中递归引用自身的表。 assign( = 覆盖式混入表,\n支持覆盖已存在的值,不支持递归混入成员表,\n此函数不复制元表。\n\ntable.mix 函数混入表但不覆盖已存在的值\ntable.clone函数递归混入成员且复制元表 assign(.(对象,任意多个混入对象->->->) = 参数@1为空则创建新表,\n使用后面的对象混入前面的对象(浅拷贝),并返回该对象\n该函数仅修改第一个参数(混入目标) ,覆盖已存在的键值\n此函数不会覆盖已存在的只读成员\n\n除参数 @1 ,其他任何参数为 null 则停止合并返回结果(也就是返回参数 @1 ) mix( = 混入表但不覆盖已存在的值,\n此函数不复制元表。 mix(.(对象,任意多个混入对象->->->) = 参数 @1 为空则创建新表\n使用后面的对象补全前面的对象(浅拷贝),并返回该对象\n该函数仅修改第一个参数(混入目标),不覆盖已存在的键值.\n可用于设置表的默认值\n\n除参数@1,其他任何参数为 null 则停止合并返回结果(也就是返回参数 @1 ) create(.(原型对象,任意多个混入对象) = 创建表对象,\n如果指定了原型表,则返回对象使用 _get 元方法指向该原型表,\n返回表对象可以共享原型表中的成员,但不会复制并存储原型表的成员\n\n如果指定了混入对象,则会将混入对象的成员实际复制到返回的表对象内,\n混入规则与 table.assign 一致,按参数顺序从前向后混入,\n忽略已存在的只读成员 gc(.(table对象,析构函数) = 指定析构函数,返回参数@1\n注意析构函数不应抛出异常,\n析构函数的 owner 参数为这里指定的 table 对象 gc(.(table对象,"析构函数名") = 指定析构函数名,返回参数@1\n函数名可以是之后创建的成员函数,\n析构函数的 owner 参数为这里指定的 table 对象,\n如果指定的成员函数在析构时为逻辑false或null值,则忽略析构.\n注意析构函数不应抛出异常 gc( = 添加对象在销毁前执行的析构函数\n按调用 table.gc 顺序的逆序析构对象,\n最后调用 table.gc 标记的对象会最先执行析构函数 gcOnly( = 创建一个被保护的对象析构函数,\n此析构函数只会在对象被自动回收时自动触发,\n主动调用此析构函数将被忽略 gcOnly(.(dtor) = @dtor 参数指定使用 table.gc 标记的析构对象的析构函数,\n此函数将返回一个新的用于覆盖原析构函数的函数,\n应将返回的析构函数重新赋值为对象的同名析构函数 namespace(__) = 创建字符串参数 @1 指定的全局命名空间,\n查询或创建命名空间不会触发元方法,\n如果名字被非表对象占用导致名称冲突则返回 null,\n成功返回该命名空间\n\n此函数的作用与 namespace 语句相同,但不会改变当前命名空间 get( = 按指定的`表路径`查找深层嵌套成员的值。\n找不到`表路径`的任何部分返回 null 而非报错。\n此函数会触发表的 _get 元方法(前提是定义了这个元方法)。 get(.(path,object) = @根据参数 @path 指定的`表路径`在参数 @object 指定的表内查找对象。\n参数 @object 可省略,默认为 global 对象。\n\n参数 @path 可使用以下语法:\n- 使用成员操作符 `.` 分隔上下级路径(直接匹配拆分,不检查标识符规则)。\n- 使用下标 `[]` 包含的表达式表示元素的键,空`[]`(仅限 `path` 参数内)表示数组最后一个元素。\n- 上述路径可以任意组合,嵌套路径从左到右逐层深入。\n\n在查找获取成员时会触发对象的 _get 元方法(前提是定义了这个元方法)。\n找不到指定路径中的任何部分时返回 null,不会报错,也不会创建指定路径的对路。\n如果找到象则返回两个值:找到的对象,为该对象所在的父对象\n\n示例:`var price,item = table.get("items[5].price",products)` set( = 按指定的`表路径`设置深层嵌套成员的值。\n`表路径`中不存在的父级路径会自动添加新的表对象。\n此函数会触发表的 _set 元方法(前提是定义了这个元方法)。 set(.(path,value,object) = @在参数 @object 指定的表内对参数 @path 指定`表路径`的成员赋值。\n参数 @object 可省略,默认为 global 对象。\n\n参数 @path 可使用以下语法:\n- 使用成员操作符 `.` 分隔上下级路径(直接匹配拆分,不检查标识符规则)。\n- 使用下标 `[]` 包含的表达式表示元素的键,空`[]`(仅限 `path` 参数内)表示在数组尾部增加新对象。\n- 上述路径可以任意组合,嵌套路径从左到右逐层深入,遇到不存在的父级路径会自动创建表对象。\n\n示例:`table.set("[5]profile.address[].city","杭州",users)` unpackArgs(.(args) = 展开稀疏数组。\n从索引 1 到最大索引返回所有元素值,包含中间的 null 值 spliceArgs( = 用于展开数组或可能包含 null 值的稀疏数组并插入目标数组中指定的位置。\nn此函数典型的应用是用于处理由不定参数转换而来的数组。\n例如 `var args = [...]` 可能会包含 null 值。\n这也是函数名称的由来。 spliceArgs(.(数组,位置,删除长度,参数表,开始索引,结束索引) = 此函数在参数 @2 指定的位置删除指定长度的元素,\n然后将参数 @4 中的指定索引范围的元素插入到该位置。\n如果未指定开始索引,结束索引则调用 table.range 获取最小最大索引。\n如果删除了元素则返回包含删除元素的数组。 eachArgs(.(args) = 稀疏数组迭代器。\n从索引 1 到最大索引迭代所有元素值,包含中间的 null 值。\n此函数典型的应用是用于遍历不定参数,这也是函数名称的由来。\n例如 `var args = [...]` 返回的数组有可能会包含 null 值,\n使用 eachArgs 则可避免遗漏参数。 shuffle(__) = 对参数中指定的数组原地随机打乱排序,\n返回原数组 map(tab,lambda) = @.map(__/*应用后面的 lambda 函数计算每个表成员的新值并返回新表,\n此函数不会修改参数中传入的表而是返回新表,\nlambda 函数的参数v为值,k为键\nnlambda 函数返回null时忽略不操作*/,lambda(v,k) v[1] ) map(tab,function) = @.map(__/*应用后面的回调函数计算每个表成员的新值并返回新表,\n此函数不会修改参数中传入的表而是返回新表,\n回调函数的参数v为值,k为键,result为返回的表\n回调函数如果不返回值或返回null时忽略不操作\n因此可选通过result修改键值而不是返回新值*/,function(v,k,result){\n \n}) mapDeep(表) = @.mapDeep(__/*应用后面的回调函数计算新值并返回新表,\n此函数不会修改参数中传入的表而是返回新表,\n如果遇到成员值是一个表时,递归调用table.mapDeep函数处理成员表,\n回调函数的参数v为值,k为键,result为当前返回的表\n回调函数如果不返回值或返回null时忽略不操作\n因此可选通过result修改键值而不是返回新值*/,function(v,k,result){\n \n}) every(表) = @.every(__/*调用后面的回调函数计算表的每个值是否符合条件*/,function(v,k){\n \n}) some(表) = @.some(__/*调用后面的回调函数计算表的任意某个值是否符合条件*/,function(v,k){\n \n}) filter(数组) = @.filter(__/*调用后面的回调函数筛选并返回新数组\n回调函数返回真值时添加该值到新数组中*/,function(v,index){\n \n}) removeByValue( = 在数组中查找指定值并移除指定值,\n此函数无返回值,直接修改参数传入的数组。 removeByValue(.(数组,值) = 在数组中查找指定值,\n并移除第一个找到的非null值,\n如果移除了元素则返回移除元素的索引,\n\n如果参数@2为null,则清除所有null值。\n\n此函数无返回值。 removeByValue(.(数组,值,true) = 在数组中查找指定值并将找到的值全部移除,\n如果参数@2为 null,则使用 table.range 函数取最大索引,\n这会导致最大索引前的所有null值都作为数组元素处理,\n建议查看此函数源码以避免错误使用导致性能降低。\n\n此函数无返回值。 clear(__) = 清空参数 @1 指定的表对象内所有键值 flat(.(array,depth) = 展开 @array 参数指定的数组中嵌套的数组并返回新数组,\n此函数不会修改传入参数而是返回新数组,\n可选用 @depth 参数指定要允许展开的嵌套深度,默认值为1 getCall( = 以 owner call 方式获取函数对象。\nowner call 指形如 `object.method()` 格式的函数调用语句。\n函数内的 owner 参数设为成员操作符前面的 object 对象。\n如果对象使用 _get 元方法返回函数,\n则 _get 元方法的 ownerCall 参数为 true 。 getCall(.(object,methodName) = 如果对象实际包含参数 @methodName 指定的成员则直接返回。\n否则模拟 `object.methodName()` 格式触发 `_get` 元方法,获取函数对象(但不会调用该函数)。\n调用 `_get` 元方法时 ownerCall 参数为 true。\n\n适用于对 `object.funcName()` , `object["funcName"]` 区分处理的对象,\n例如 .NET 对象。 getAttr( = 调用成员(属性)操作符获取对象的键值。 getAttr(.(object,key) = 如果对象实际包含 @key 参数指定键的值则直接返回。\n否则调用 _get 元方法获取指定键的值,元方法第 3 个参数(@ownnerCall)设为 false。 \n使用索引下标 [] 获取键值触发 _get 元方法时 @ownnerCall 参数为 null 。 setAttr( = 调用成员(属性)操作符修改对象的键值。 setAttr(.(object,key) = 如果对象实际包含 @key 参数指定键的值则直接修改。 \n否则调用 _set 元方法修改指定键的值,元方法第 3 个参数(@ownnerAttr)设为 true。 \n使用索引下标 [] 修改键值触发 _set 元方法时 ownnerAttr 参数为 false 。 parseValue(__) = 如果参数不是表则直接返回,\n否则将表(table)转换为纯值表。\n\n如果对象定义了 _json 元方法,\n则调用该元方法返回值(返回值 2 为 true 时不采用其结果)。\n_json 元方法通常会返回纯值或者类纯值类型,但不一定是表对象,\ntable.parseValue 只会原样返回通过 _json 元方法获取的值,不作其他处理。\n\n纯值表只包含纯值类型数据。\n纯值类型指的是字符串、数值、布尔值、buffer、指针、纯值表。\n纯值表必须遵守规则如下:\n1. 索引只能为数值或者字符串,移除其他索引。\n2. 移除类型为 function,class,fiber,cdata 成员,值为表则必须也是纯值表。\n3. 表要么是索引自1开始的有序稠密数组,要么是只包含名值对的对象,只能二选一。\n 如果传入对象是纯数组或类数组(使用 table.isArrayLike 判断),则返回为新的纯数组。\n4. 纯值表的所有数据都直接保存在表中,也就是用直接下标可以获取所有值。\n5. 纯值表是可保持原值序列化的表,并且兼容 JSON。 \n\nJSON.strip 函数的转换结果也属于纯值 invert(__) = 翻转参数 @1 指定表对象的键值对,\n使值变为键,键变为值。 end intellisense**/