Si Expression 实际操作要点
- 格式:pdf
- 大小:2.32 MB
- 文档页数:28
cronexpression类的方法【实用版】目录1.引言:CronExpression类的概述2.CronExpression类的主要方法2.1 parse方法:解析Cron表达式2.2 next方法:计算下一个满足Cron表达式的时间2.3 previous方法:计算上一个满足Cron表达式的时间2.4 isSatisfiedBy方法:判断给定时间是否满足Cron表达式3.方法使用示例4.总结:CronExpression类的方法功能与使用价值正文CronExpression类是用于处理和操作Cron表达式的工具类。
Cron表达式是一种用于表示定时任务执行时间的字符串格式。
CronExpression 类提供了一系列方法来解析、计算和验证Cron表达式,帮助开发者更方便地使用和管理定时任务。
首先,parse方法是CronExpression类的核心方法之一。
它通过解析Cron表达式字符串,将其转换为内部可处理的对象表示形式。
开发者可以通过该方法将Cron表达式字符串转换为CronExpression对象,从而进行后续的计算和验证操作。
接下来,next方法和previous方法分别用于计算下一个和上一个满足Cron表达式的时间点。
这两个方法对于确定定时任务的执行时间非常有用。
开发者可以传入一个起始时间,然后调用next方法或previous方法,获取下一个或上一个满足Cron表达式的时间点。
另外,isSatisfiedBy方法用于判断给定的时间是否满足Cron表达式的条件。
该方法接受一个时间参数,返回一个布尔值,指示给定时间是否匹配Cron表达式。
这在验证定时任务执行时间是否符合预期时非常有用。
以下是使用CronExpression类方法的示例代码:```java// 解析Cron表达式CronExpression cronExpression = CronExpression.parse("0 0 0 * * ?");// 计算下一个满足Cron表达式的时间Date nextTime = cronExpression.next(new Date());// 判断给定时间是否满足Cron表达式Date givenTime = new Date();boolean isSatisfied =cronExpression.isSatisfiedBy(givenTime);```总结起来,CronExpression类提供了多种方法,帮助开发者解析、计算和验证Cron表达式,以便更好地管理和使用定时任务。
delegate()方法摘要:1.了解delegate()方法的定义和作用2.分析delegate()方法的应用场景3.探讨delegate()方法在编程实践中的优势和局限性4.总结delegate()方法在编程中的重要性正文:在编程领域,特别是面向对象编程中,delegate(代表)方法是一个重要概念。
它允许开发者将一个方法的调用转移给另一个方法,实现代码的解耦和模块化。
本文将详细介绍delegate()方法的概念、应用场景、优势和局限性,以及其在编程中的重要性。
1.了解delegate()方法的定义和作用Delegate(代表)方法是一种将方法调用转移的技术,它允许开发者将一个方法的调用封装成一个对象,然后将这个对象传递给另一个方法。
在C#、Java等面向对象编程语言中,delegate被称为“委托”(英文:Callback)。
通过使用delegate,我们可以将方法的调用过程从原本的方法中分离出来,实现代码的模块化和解耦。
2.分析delegate()方法的应用场景delegate方法在以下几种场景下非常有用:(1)事件处理:在GUI编程中,当用户与界面交互时,例如点击按钮、选择列表框等,我们需要为这些事件编写处理方法。
使用delegate可以将事件处理方法与事件源进行解耦,提高代码的可维护性。
(2)回调函数:在某些情况下,我们需要在某个方法执行过程中,根据特定条件调用其他方法。
通过使用delegate,可以将这个回调过程封装成一个对象,方便在需要时进行调用。
(3)异步编程:在涉及到网络请求、文件操作等耗时操作时,我们需要使用异步编程。
delegate可以用于封装异步操作的完成事件,以便在操作完成后执行相应的方法。
3.探讨delegate()方法在编程实践中的优势和局限性优势:(1)代码解耦:delegate方法有助于实现代码的解耦,提高代码的可维护性和可读性。
(2)灵活性:delegate方法使得程序可以在运行时动态地添加或删除处理方法,提高程序的灵活性。
strsep函数strsep函数________________________strsep函数是一种常用的字符串处理函数,它的功能是从一个源字符串中提取字符串,并以字符串形式返回。
它的主要用途是用来分割字符串,以提取出其中的某些部分。
这种函数经常被用于解析字符串,比如配置文件、参数列表、命令行参数等。
strsep函数是一个C语言中比较流行的函数,它由GNU C库提供,也可以在其他C语言库中找到。
它接受两个参数:一个是源字符串,一个是分隔符。
分隔符可以是一个字符或者一个字符串,strsep函数会把这个字符或者字符串当作一个单元进行处理。
strsep函数的工作原理是:它会在源字符串中查找分隔符,然后将源字符串分割成两部分。
其中一部分会以字符串的形式返回,这就是我们要提取的部分;而另一部分则会被修改,在修改后的部分中,将不再包含分隔符。
strsep函数还有一些额外的特性。
首先,它会跳过前导空格;而其次,如果输入的源字符串以分隔符开头,那么strsep函数会返回一个NULL值。
使用strsep函数的方法也很简单。
首先,我们需要定义一个char *类型的变量,用来接收strsep函数的返回值。
然后,将源字符串作为参数传入strsep函数,以及我们想要使用的分隔符。
最后,strsep函数将会把提取出来的字符串返回给我们定义的char *类型变量。
例如,如果我们想要从一个字符串“Hello World”中提取出“World”,那么我们就可以使用strsep函数:char *str = “Hello World”; // 定义原始字符串char *resu lt = strsep(&str, “ ”); // 使用strsep函数提取字符串printf("%s\n", result); // 输出"World"当然,strsep函数也可以用于其他的应用场景。
例如,如果我们想要解析一个配置文件,那么我们就可以使用strsep函数来实现。
si使⽤技巧黄⾊的#符号是Directive即指⽰器绿⾊的M符号是Micro即宏蓝⾊的椭圆代表Global Variable即全局变量绿⾊的梯形代表Function即函数source insight 使⽤技巧[嵌⼊式]发布时间:2008-11-03 17:15:161 开胃菜-初级应⽤1.1 选择美丽的界⾯享受⼯作虽然不能以貌取⼈,但似乎从来没有⼈责备以貌取软件的。
SI的华丽界⾯,绝对符合现代花花世界的⼈的审美趣味。
在SI中,我们可以轻松地把各种类型关键字、变量、标志符、函数、宏、注释等定义为不同的颜⾊和显⽰⽅式(正体或斜体、加粗或正常、加下划线、放⼤显⽰等),总有⼀种⽅式能让我们⼀眼就能分辨出这个标识是什么。
1.1.1 字体选择在SI中样式是可以被继承,如果要从根本上改变字体,最简单的⽅式就是直接修改根样式中的字体,因为其它样式都会由此继承⽽来。
选择Options/Document Options页⾯内的F ont Options中的ScreenFonts字体,即可改变根样式中的字体。
SI中的默认配置为Verd ana字体,是⼀种⾮等宽字体,为了使编写的代码在各种编辑器中看起来都有良好的对齐效果,这⾥强烈建议使⽤等宽字体,Courier、New Courier和宋体等都是较好的选择。
1.1.2 颜⾊定义毕竟这是见仁见智的东西,所以从来没有统⼀的标准。
很多⼈并不喜欢SI提供的默认配置,那么我们就改吧。
选择Options/Style Properties页⾯,就可以在其中修改所有样式了。
选择等号(=)表⽰继承ParentStyle,也可以选择Pick(或者ON/OFF等)去配置⼀个新值。
这完全视乎个⼈喜好。
1.1.3 标识符样式选择在与颜⾊定义⼀节同样的界⾯内即可完成此项配置。
1.1.4 背景⾊选择在希望要改变背景⾊的窗⼝点击⿏标右键(假定使⽤的是右⼿⿏标),选择上下⽂菜单的xxx Window Properties项,然后点击弹出窗⼝的BackColor按钮,即可修改该窗⼝背景⾊。
Expression核⼼操作符、表达式、操作⽅法⼀、Expression中的操作运算符成员名称说明Add加法运算,如 a + b, ,不进⾏溢出检查,针对数值操作数。
AddAssign加法复合赋值运算,如 (a += b), ,不进⾏溢出检查,针对数值操作数。
AddAssignChecked加法复合赋值运算,如 (a += b), ,进⾏溢出检查,针对数值操作数。
AddChecked加法运算,如 (a + b), ,进⾏溢出检查,针对数值操作数。
And按位或逻辑 AND 操作,如 (a & b) 在 C# 和 (a And b) 在 Visual Basic 中。
AndAlso在条件 AND 仅当第⼀个操作数的计算结果为才计算第⼆个操作数的操作 true。
它对应于 (a && b) 在 C# 和 (a AndAlso b) 在 Visual Basic 中。
AndAssign按位或逻辑 AND 复合赋值运算,如 (a &= b) C# 中。
ArrayIndex索引操作在⼀维数组中,如 array[index] 在 C# 或 array(index) 在 Visual Basic 中。
ArrayLength获取⼀维数组的长度,如操作 array.Length。
Assign赋值运算,如 (a = b)。
Block表达式的块。
Call某个⽅法调⽤,如在 obj.sampleMethod() 表达式。
Coalesce⼀个表⽰空合并操作,如节点 (a ?? b) 在 C# 或 If(a, b) 在 Visual Basic 中。
Conditional条件运算,如 a > b ? a : b 在 C# 或 If(a > b, a, b) 在 Visual Basic 中。
Constant常量的值。
Convert强制转换或转换操作中,如 (SampleType)obj C# 中或 CType(obj, SampleType) 在 Visual Basic 中。
Exception类的常用方法(1) getMessage(方法:该方法返回一个字符串,用于描述异常的详细信息。
通常,这个信息会包含异常的类型、异常发生的位置以及其他与异常相关的信息。
(2) printStackTrace(方法:该方法将异常的跟踪信息打印到标准错误流中。
这个跟踪信息包括异常发生的位置以及异常调用栈的详细信息。
通常,这个方法用于调试和诊断异常时使用。
(3) getCause(方法:该方法返回一个Throwable对象,表示引发当前异常的原因。
如果异常是由其他异常引发的,那么getCause(方法返回的Throwable对象就是引发异常的原因。
如果异常是由其他原因引发的,那么getCause(方法返回null。
(4) getLocalizedMessage(方法:该方法返回一个本地化的描述方式,用于解释异常。
通常,这个描述信息是异常类的子类提供的,包含异常的类型和其他相关信息。
(5) getClass(方法:该方法返回表示该异常类的Class对象。
通常,可以使用getClass(方法来判断异常对象的类型,从而进行特定的处理。
(6) equals(方法:该方法比较两个异常对象是否相等。
如果两个异常对象的类型、描述信息以及其他相关信息都相同,则equals(方法返回true。
(7) hashCode(方法:该方法返回异常对象的哈希码。
通常,hashCode(方法的实现基于异常对象的类型、描述信息以及其他相关信息的哈希值来计算。
(8) toString(方法:该方法返回异常对象的字符串表示形式。
通常,这个字符串包含异常类的名称以及其他相关信息。
(9) fillInStackTrace(方法:该方法用于重新设置异常对象的调用栈。
通常,这个方法在异常被重新抛出时使用,以便重新设置异常的调用栈信息。
(10) initCause(方法:该方法用于设置异常对象的原因。
通常情况下,异常对象是由其他异常对象引发的,使用initCause(方法可以将引发异常的原因设置为新的异常对象。
C#Expression详解(⾼级)LINQ在本地查询IEnumerbale主要是⽤委托来作为传参,⽽解析型查询IQueryable则⽤Expression来作为传参:public static IEnumerable<T> Where<T>(this IEnumerable<T> enumable, Func<T, bool> func)public static IQueryable<T> Where<T>(this IQueryable<T> queryable, Expression<Func<T, bool>> func)⼀、Expression是什么1、如何定义Expression<Func<TSource, bool>>就是表达式⽬录树Expression不能带有⼤括号,只能有⼀⾏代码2、和委托的区别在委托外⾯包裹⼀层Expression<>就是表达式⽬录树表达式⽬录树可以通过Compile()转换成⼀个委托3、Expression本质表达式⽬录树是⼀个类的封装,描述了⼀个结构,有⾝体部分和参数部分⾝体部分分为左边和右边,内部描述了左边和右边之间的关系,可以不断的往下拆分,类似于⼆叉树表达式⽬录树展开后的每⼀个节点也是⼀个表达式⽬录树Expression<Func<People, bool>> expression = p => p.Id == 10;Func<People, bool> func = pile();bool bResult = func.Invoke(new People(){Id = 10,Name = "张三"});⼆、Expression与Expression Tree⾸先我们来写下⼀些代码:Expression<Func<int, int>> expression = (num) => num + 5;Console.WriteLine($"NodeType:{expression.NodeType}");Console.WriteLine($"Body:{expression.Body}");Console.WriteLine($"Body Type: {expression.Body.GetType()}");Console.WriteLine($"Body NodeType: {expression.Body.NodeType}");输出如下:NodeType:LambdaBody:(num + 5)Body Type: System.Linq.Expressions.SimpleBinaryExpressionBody NodeType: Add我们将expression转为LambdaExpression看看都有啥:if (expression.NodeType == mbda){var lambda = (LambdaExpression)expression;var parameter = lambda.Parameters.Single();Console.WriteLine($":{}");Console.WriteLine($"parameter.Type:{parameter.Type}");Console.WriteLine($"parameter.ReturnType:{lambda.ReturnType}");}输出如下::numparameter.Type:System.Int32parameter.ReturnType:System.Int32由于我们知道expression.Body是BinaryExpression,那么我们就将其转为它,然后我们继续看下去:if (expression.Body.NodeType == ExpressionType.Add){var binaryExpreesion = (BinaryExpression)expression.Body;Console.WriteLine($"Left Type:{binaryExpreesion.Left.GetType()}");Console.WriteLine($"Left NodeType:{binaryExpreesion.Left.NodeType}");Console.WriteLine($"Right Type:{binaryExpreesion.Right.GetType()}");Console.WriteLine($"Right NodeType:{binaryExpreesion.Right.NodeType}");if (binaryExpreesion.Left is ParameterExpression parameterExpreesion){Console.WriteLine($":{}");Console.WriteLine($"parameterExpreesion.Type:{parameterExpreesion.Type}");}if (binaryExpreesion.Right is ConstantExpression constantExpreesion){Console.WriteLine($"constantExpreesion.Value:{constantExpreesion.Value}" );}}输出如下:Left Type:System.Linq.Expressions.PrimitiveParameterExpression`1[System.Int32]Left NodeType:ParameterRight Type:System.Linq.Expressions.ConstantExpressionRight NodeType:Constant:numparameterExpreesion.Type:System.Int32constantExpreesion.Value:5最后我们将表达式树转为委托:var @delegate = pile();Console.WriteLine(@delegate?.Invoke(2));输出:7 //2+5实际上,通过Expression<Func<int, int>> expression = (num) => num + 5;,赋值后的expression变成了⼀个表达式树,它的结构是这样的:⽽有意思的是⼆元表达式树BinaryExpression是⼀个⼆叉树,⽽LambdaExpression则是⼀个⽀持参数的表达式,能够通过其Parameters属性知道传⼊的参数的类型和数量,通过ReturnType知道返回值是什么类型⽽我们再看看整个关于Expression的继承关系链:因此,我们也可以显式的通过各⾃Expreesion的实现⼦类来创建跟lambda表达式⼀样的结果:var parameterExpreesion1 = Expression.Parameter(typeof(int), "num");BinaryExpression binaryExpression1 = Expression.MakeBinary(ExpressionType.Add, parameterExpreesion1, Expression.Constant(5));Expression<Func<int, int>> expression1 = mbda<Func<int, int>>(binaryExpression1, parameterExpreesion1);if (expression1.Body.NodeType == ExpressionType.Add){var binaryExpreesion1 = (BinaryExpression)expression1.Body;Console.WriteLine($"Left Type:{binaryExpreesion1.Left.GetType()}");Console.WriteLine($"Left NodeType:{binaryExpreesion1.Left.NodeType}");Console.WriteLine($"Right Type:{binaryExpreesion1.Right.GetType()}");Console.WriteLine($"Right NodeType:{binaryExpreesion1.Right.NodeType}");if (binaryExpreesion1.Left is ParameterExpression parameterExpreesion2){Console.WriteLine($":{}");Console.WriteLine($"parameterExpreesion.Type:{parameterExpreesion2.Type}");}if (binaryExpreesion1.Right is ConstantExpression constantExpreesion1){Console.WriteLine($"constantExpreesion.Value:{constantExpreesion1.Value}");}var @delegate1 = pile();Console.WriteLine(@delegate1(2));输出结果:Left Type:System.Linq.Expressions.PrimitiveParameterExpression`1[System.Int32]Left NodeType:ParameterRight Type:System.Linq.Expressions.ConstantExpressionRight NodeType:Constant:numparameterExpreesion.Type:System.Int32constantExpreesion.Value:5result:7我们则发现,结果是⼀模⼀样的,但是费劲了很多,因此⽤lamda构建表达式树是⼀个⾮常愉快的语法糖,让你能够愉快的在使⽤表达式和表达式树三、Expression动态拼装1、最基础版本Expression<Func<int>> expression = () => 123 + 234;//常量表达式ConstantExpression expression1 = Expression.Constant(123);ConstantExpression expression2 = Expression.Constant(234);//⼆元表达式BinaryExpression binaryExpression = Expression.Add(expression1, expression2);Expression<Func<int>> expressionReslut = mbda<Func<int>>(binaryExpression);Func<int> func = pile();int iResult = func.Invoke();2、带参数版本Expression<Func<int, int>> expression1 = m => m + 1;Func<int, int> func = pile();int iResult = func.Invoke(5);//参数表达式ParameterExpression parameterExpression = Expression.Parameter(typeof(int), "m");//常量表达式ConstantExpression constant = Expression.Constant(1, typeof(int));//⼆元表达式BinaryExpression addExpression = Expression.Add(parameterExpression, constant);Expression<Func<int, int>> expression = mbda<Func<int, int>>(addExpression, new ParameterExpression[1]{parameterExpression});Func<int, int> func1 = pile();int iResult1 = func1.Invoke(5);3、带有多个参数Expression<Func<int, int, int>> expression = (m, n) => m * n + 2;Func<int, int, int> func = pile();int iResult = func.Invoke(10, 20);//参数表达式ParameterExpression parameterExpressionM = Expression.Parameter(typeof(int), "m");ParameterExpression parameterExpressionN = Expression.Parameter(typeof(int), "n");//⼆元表达式BinaryExpression multiply = Expression.Multiply(parameterExpressionM, parameterExpressionN);//常量表达式ConstantExpression constantExpression = Expression.Constant(2);//⼆元表达式BinaryExpression plus = Expression.Add(multiply, constantExpression);Expression<Func<int, int, int>> expression1 = mbda<Func<int, int, int>>(plus, new ParameterExpression[2]{parameterExpressionM,parameterExpressionN});Func<int, int, int> func1 = pile();int iResult1 = func1.Invoke(10, 20);4、对象字段值⽐较类似于这种⽐较复杂的,建议⼤家可以反编译看看Expression<Func<People, bool>> predicate = c => c.Id == 10;Func<People, bool> func = pile();bool bResult = func.Invoke(new People(){Id = 10});//参数表达式ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "c");//反射获取属性FieldInfo fieldId = typeof(People).GetField("Id");//通过parameterExpression来获取调⽤IdMemberExpression idExp = Expression.Field(parameterExpression, fieldId);//常量表达式ConstantExpression constant10 = Expression.Constant(10, typeof(int));//⼆元表达式BinaryExpression expressionExp = Expression.Equal(idExp, constant10);Expression<Func<People, bool>> predicate1 = mbda<Func<People, bool>>(expressionExp, new ParameterExpression[1] {parameterExpression});Func<People, bool> func1 = pile();bool bResult1 = func1.Invoke(new People(){Id = 10});5、多条件如果遇到很长的表达式⽬录树,拼装建议从右往左拼装Expression<Func<People, bool>> predicate = c => c.Id.ToString() == "10" && .Equals("张三") && c.Age > 35; Func<People, bool> func = pile();bool bResult = func.Invoke(new People(){Id = 10,Name = "张三",Age = 36});ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "c");//c.Age > 35ConstantExpression constant35 = Expression.Constant(35);PropertyInfo propAge = typeof(People).GetProperty("Age");MemberExpression ageExp = Expression.Property(parameterExpression, propAge);BinaryExpression cagExp = Expression.GreaterThan(ageExp, constant35);//.Equals("张三")ConstantExpression constantrichard = Expression.Constant("张三");PropertyInfo propName = typeof(People).GetProperty("Name");MemberExpression nameExp = Expression.Property(parameterExpression, propName);MethodInfo equals = typeof(string).GetMethod("Equals", new Type[] { typeof(string) });MethodCallExpression NameExp = Expression.Call(nameExp, equals, constantrichard);//c.Id.ToString() == "10"ConstantExpression constantExpression10 = Expression.Constant("10", typeof(string));FieldInfo fieldId = typeof(People).GetField("Id");var idExp = Expression.Field(parameterExpression, fieldId);MethodInfo toString = typeof(int).GetMethod("ToString", new Type[0]);var toStringExp = Expression.Call(idExp, toString, Array.Empty<Expression>());var EqualExp = Expression.Equal(toStringExp, constantExpression10);//c.Id.ToString() == "10"&& .Equals("张三")&& c.Age > 35var plus = Expression.AndAlso(EqualExp, NameExp);var exp = Expression.AndAlso(plus, cagExp);Expression<Func<People, bool>> predicate1 = mbda<Func<People, bool>>(exp, new ParameterExpression[1] {parameterExpression});Func<People, bool> func1 = pile();bool bResult1 = func1.Invoke(new People(){Id = 10,Name = "张三",Age = 36});四、Expression应⽤之Mapper映射需求:需要把People字段值映射到PeopleCopy字段1、硬编码性能好,不灵活;不能共⽤PeopleCopy peopleCopy0 = new PeopleCopy(){Id = people.Id,Name = ,Age = people.Age};2、反射灵活,但是性能不好using System;namespace MyExpression.MappingExtend{public class ReflectionMapper{/// <summary>/// 反射/// </summary>/// <typeparam name="TIn"></typeparam>/// <typeparam name="TOut"></typeparam>/// <param name="tIn"></param>/// <returns></returns>public static TOut Trans<TIn, TOut>(TIn tIn){TOut tOut = Activator.CreateInstance<TOut>();foreach (var itemOut in tOut.GetType().GetProperties()){var propIn = tIn.GetType().GetProperty();itemOut.SetValue(tOut, propIn.GetValue(tIn));}foreach (var itemOut in tOut.GetType().GetFields()){var fieldIn = tIn.GetType().GetField();itemOut.SetValue(tOut, fieldIn.GetValue(tIn));}return tOut;}}}调⽤PeopleCopy peopleCopy1 = ReflectionMapper.Trans<People, PeopleCopy>(people);3、序列化灵活,但是性能不好using Newtonsoft.Json;namespace MyExpression.MappingExtend{public class SerializeMapper{/// <summary>/// 序列化/// </summary>/// <typeparam name="TIn"></typeparam>/// <typeparam name="TOut"></typeparam>public static TOut Trans<TIn, TOut>(TIn tIn){string strJson = JsonConvert.SerializeObject(tIn);return JsonConvert.DeserializeObject<TOut>(strJson);}}}调⽤PeopleCopy peopleCopy2 = SerializeMapper.Trans<People, PeopleCopy>(people);4、Expression动态拼接+普通缓存把People变成PeopleCopy的过程封装在⼀个委托中,这个委托通过表达式⽬录树Compile出来,过程动态拼装适应不同的类型第⼀次⽣成的时候,保存⼀个委托在缓存中,如果第⼆次来,委托就可以直接从缓存中获取到,直接运⾏委托,效率⾼using System;using System.Collections.Generic;using System.Linq.Expressions;namespace MyExpression.MappingExtend{public class ExpressionMapper{/// <summary>/// 字典缓存,保存的是委托,委托内部是转换的动作/// </summary>private static Dictionary<string, object> _Dic = new Dictionary<string, object>();/// <summary>/// Expression动态拼接+普通缓存/// </summary>/// <typeparam name="TIn"></typeparam>/// <typeparam name="TOut"></typeparam>/// <param name="tIn"></param>/// <returns></returns>public static TOut Trans<TIn, TOut>(TIn tIn){string key = $"funckey_{typeof(TIn).FullName}_{typeof(TOut).FullName}";if (!_Dic.ContainsKey(key)){ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "p");List<MemberBinding> memberBindingList = new List<MemberBinding>();foreach (var item in typeof(TOut).GetProperties()){MemberExpression property = Expression.Property(parameterExpression, typeof(TIn).GetProperty());MemberBinding memberBinding = Expression.Bind(item, property);memberBindingList.Add(memberBinding);foreach (var item in typeof(TOut).GetFields()){MemberExpression property = Expression.Field(parameterExpression, typeof(TIn).GetField());MemberBinding memberBinding = Expression.Bind(item, property);memberBindingList.Add(memberBinding);}MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray()); Expression<Func<TIn, TOut>> lambda = mbda<Func<TIn, TOut>>(memberInitExpression, new ParameterExpression[] {parameterExpression});Func<TIn, TOut> func = pile();//拼装是⼀次性的_Dic[key] = func;}return ((Func<TIn, TOut>)_Dic[key]).Invoke(tIn);}}}调⽤PeopleCopy peopleCopy3 = ExpressionMapper.Trans<People, PeopleCopy>(people);5、Expression动态拼接+泛型缓存泛型缓存,就是为每⼀组类型的组合,⽣成⼀个副本,性能最⾼using System;using System.Collections.Generic;using System.Linq.Expressions;namespace MyExpression.MappingExtend{/// <summary>/// Expression动态拼接+泛型缓存/// </summary>/// <typeparam name="TIn"></typeparam>/// <typeparam name="TOut"></typeparam>public class ExpressionGenericMapper<TIn, TOut>//Mapper`2{private static Func<TIn, TOut> _FUNC = null;static ExpressionGenericMapper(){ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "p");List<MemberBinding> memberBindingList = new List<MemberBinding>();foreach (var item in typeof(TOut).GetProperties()){MemberExpression property = Expression.Property(parameterExpression, typeof(TIn).GetProperty());MemberBinding memberBinding = Expression.Bind(item, property);memberBindingList.Add(memberBinding);}foreach (var item in typeof(TOut).GetFields()){MemberExpression property = Expression.Field(parameterExpression, typeof(TIn).GetField());MemberBinding memberBinding = Expression.Bind(item, property);memberBindingList.Add(memberBinding);}MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray()); Expression<Func<TIn, TOut>> lambda = mbda<Func<TIn, TOut>>(memberInitExpression, new ParameterExpression[] {parameterExpression});_FUNC = pile();//拼装是⼀次性的}public static TOut Trans(TIn t){return _FUNC(t);}}}调⽤PeopleCopy peopleCopy4 = ExpressionGenericMapper<People, PeopleCopy>.Trans(people);6、性能⽐较Expression动态拼接+泛型缓存性能⾼,⽽且灵活long common = 0;long generic = 0;long reflection = 0;long serialize = 0;{Stopwatch watch = new Stopwatch();watch.Start();for (int i = 0; i < 1_000_000; i++){PeopleCopy peopleCopy = new PeopleCopy(){Id = people.Id,Name = ,Age = people.Age};}watch.Stop();common = watch.ElapsedMilliseconds;}{Stopwatch watch = new Stopwatch();watch.Start();for (int i = 0; i < 1_000_000; i++){PeopleCopy peopleCopy = ReflectionMapper.Trans<People, PeopleCopy>(people);}watch.Stop();reflection = watch.ElapsedMilliseconds;}{Stopwatch watch = new Stopwatch();watch.Start();for (int i = 0; i < 1_000_000; i++){PeopleCopy peopleCopy = SerializeMapper.Trans<People, PeopleCopy>(people);}watch.Stop();serialize = watch.ElapsedMilliseconds;}{Stopwatch watch = new Stopwatch();watch.Start();for (int i = 0; i < 1_000_000; i++){PeopleCopy peopleCopy = ExpressionMapper.Trans<People, PeopleCopy>(people);}watch.Stop();cache = watch.ElapsedMilliseconds;}{Stopwatch watch = new Stopwatch();watch.Start();for (int i = 0; i < 1_000_000; i++){PeopleCopy peopleCopy = ExpressionGenericMapper<People, PeopleCopy>.Trans(people);}watch.Stop();generic = watch.ElapsedMilliseconds;}Console.WriteLine($"common = { common} ms");Console.WriteLine($"reflection = { reflection} ms");Console.WriteLine($"serialize = { serialize} ms");Console.WriteLine($"cache = { cache} ms");Console.WriteLine($"generic = { generic} ms");运⾏结果common = 32 msreflection = 1026 msserialize = 2510 mscache = 236 msgeneric = 31 ms五、ExpressionVisitor解析Expression1、Expression解析Expression是通过访问者模式进⾏解析的,官⽅提供了ExpressionVisitor抽象类ExpressionVisitor的Visit⽅法是解析表达式⽬录树的⼀个⼊⼝,Visit⽅法判断Expression是⼀个什么表达式⽬录树,⾛不同的细分⽅法进⾏进⼀步解析ExpressionVisitor的VisitBinary⽅法是对⼆元表达式的解析,所有复杂的表达式都会拆解成⼆元表达式进⾏解析2、Expression修改⾃定义⼀个OperationsVisitor,继承⾃ExpressionVisitor,复写⽗类的VisitBinary⽅法,修改Expression的解析OperationsVisitor定义using System.Linq.Expressions;namespace MyExpression{/// <summary>/// ⾃定义Visitor/// </summary>public class OperationsVisitor : ExpressionVisitor{/// <summary>/// 覆写⽗类⽅法;//⼆元表达式的访问/// 把表达式⽬录树中相加改成相减,相乘改成相除/// </summary>/// <param name="b"></param>/// <returns></returns>protected override Expression VisitBinary(BinaryExpression b){if (b.NodeType == ExpressionType.Add)//相加{Expression left = this.Visit(b.Left);Expression right = this.Visit(b.Right);return Expression.Subtract(left, right);//相减}else if (b.NodeType==ExpressionType.Multiply) //相乘{Expression left = this.Visit(b.Left);Expression right = this.Visit(b.Right);return Expression.Divide(left, right); //相除}return base.VisitBinary(b);}}}Expression解析转换Expression<Func<int, int, int>> exp = (m, n) => m * n + 2;Console.WriteLine(exp.ToString());OperationsVisitor visitor = new OperationsVisitor();Expression expNew = visitor.Visit(exp);Console.WriteLine(expNew.ToString());运⾏结果(m, n) => ((m * n) + 2)(m, n) => ((m / n) - 2)3、封装多条件连接扩展⽅法扩展⽅法实现/// <summary>/// 合并表达式 And Or Not扩展⽅法/// </summary>public static class ExpressionExtend{/// <summary>/// 合并表达式 expr1 AND expr2/// </summary>/// <typeparam name="T"></typeparam>/// <param name="expr1"></param>/// <param name="expr2"></param>/// <returns></returns>public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2){if (expr1 == null || expr2 == null){throw new Exception("null不能处理");}ParameterExpression newParameter = Expression.Parameter(typeof(T), "x");NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter);Expression left = visitor.Visit(expr1.Body);Expression right = visitor.Visit(expr2.Body);BinaryExpression body = Expression.And(left, right);return mbda<Func<T, bool>>(body, newParameter);}/// <summary>/// 合并表达式 expr1 or expr2/// </summary>/// <typeparam name="T"></typeparam>/// <param name="expr1"></param>/// <param name="expr2"></param>/// <returns></returns>public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2) {if (expr1 == null || expr2 == null){throw new Exception("null不能处理");}ParameterExpression newParameter = Expression.Parameter(typeof(T), "x");NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter);Expression left = visitor.Visit(expr1.Body);Expression right = visitor.Visit(expr2.Body);BinaryExpression body = Expression.Or(left, right);return mbda<Func<T, bool>>(body, newParameter);}/// <summary>/// 表达式取⾮/// </summary>/// <typeparam name="T"></typeparam>/// <param name="expr"></param>/// <returns></returns>public static Expression<Func<T, bool>> Not<T>(this Expression<Func<T, bool>> expr){if (expr == null){throw new Exception("null不能处理");}ParameterExpression newParameter = expr.Parameters[0];UnaryExpression body = Expression.Not(expr.Body);return mbda<Func<T, bool>>(body, newParameter);}}⾃定义Visitorinternal class NewExpressionVisitor : ExpressionVisitor{public ParameterExpression _NewParameter { get; private set; }public NewExpressionVisitor(ParameterExpression param){this._NewParameter = param;}protected override Expression VisitParameter(ParameterExpression node){return this._NewParameter;}}数据过滤⽅法定义/// <summary>/// 筛选数据执⾏/// </summary>/// <param name="func"></param>private static void Do(Expression<Func<People, bool>> func){List<People> people = new List<People>(){new People(){Id=4,Name="123",Age=4},new People(){Id=5,Name="234",Age=5},new People(){Id=6,Name="345",Age=6},};List<People> peopleList = people.Where(pile()).ToList();}Expression拼接Expression<Func<People, bool>> lambda1 = x => x.Age > 5;Expression<Func<People, bool>> lambda2 = x => x.Id > 5;Expression<Func<People, bool>> lambda3 = lambda1.And(lambda2);//且Expression<Func<People, bool>> lambda4 = lambda1.Or(lambda2);//或Expression<Func<People, bool>> lambda5 = lambda1.Not();//⾮Do(lambda3);Do(lambda4);Do(lambda5);六、ExpressionVisitor应⽤之ToSql需求:实现ORM框架Expression映射成SQL⾃定义⼀个ConditionBuilderVisitor继承⾃ExpressionVisitor,复写⽗类的⽅法,Expression解析过程中实现SQL的拼接using System;using System.Collections.Generic;using System.Linq.Expressions;using System.Reflection;namespace MyExpression{public class ConditionBuilderVisitor : ExpressionVisitor{private Stack<string> _StringStack = new Stack<string>();/// <summary>/// 返回拼装好的sql条件表达式/// </summary>/// <returns></returns>public string Condition(){string condition = string.Concat(this._StringStack.ToArray());this._StringStack.Clear();return condition;}/// <summary>/// 如果是⼆元表达式/// </summary>/// <param name="node"></param>/// <returns></returns>protected override Expression VisitBinary(BinaryExpression node){if (node == null) throw new ArgumentNullException("BinaryExpression");this._StringStack.Push(")");base.Visit(node.Right);//解析右边this._StringStack.Push(" " + ToSqlOperator(node.NodeType) + " ");base.Visit(node.Left);//解析左边this._StringStack.Push("(");return node;}/// <summary>/// 解析属性/// </summary>/// <param name="node"></param>/// <returns></returns>protected override Expression VisitMember(MemberExpression node){if (node == null) throw new ArgumentNullException("MemberExpression");if (node.Expression is ConstantExpression){var value1 = this.InvokeValue(node);var value2 = this.ReflectionValue(node);this._StringStack.Push("'" + value2 + "'");}else{this._StringStack.Push(" [" + + "] ");}return node;}private string ToSqlOperator(ExpressionType type){switch (type){case (ExpressionType.AndAlso):case (ExpressionType.And):return "AND";case (ExpressionType.OrElse):case (ExpressionType.Or):return "OR";case (ExpressionType.Not):return "NOT";case (ExpressionType.NotEqual):return "<>";case ExpressionType.GreaterThan:return ">";case ExpressionType.GreaterThanOrEqual:return ">=";case ExpressionType.LessThan:return "<";case ExpressionType.LessThanOrEqual:return "<=";case (ExpressionType.Equal):return "=";default:throw new Exception("不⽀持该⽅法");}}private object InvokeValue(MemberExpression member){var objExp = Expression.Convert(member, typeof(object));//struct需要return mbda<Func<object>>(objExp).Compile().Invoke();}private object ReflectionValue(MemberExpression member){var obj = (member.Expression as ConstantExpression).Value;return (member.Member as FieldInfo).GetValue(obj);}/// <summary>/// 常量表达式/// </summary>/// <param name="node"></param>/// <returns></returns>protected override Expression VisitConstant(ConstantExpression node){if (node == null) throw new ArgumentNullException("ConstantExpression"); this._StringStack.Push("" + node.Value + "");return node;}/// <summary>/// ⽅法表达式/// </summary>/// <param name="m"></param>/// <returns></returns>protected override Expression VisitMethodCall(MethodCallExpression m){if (m == null) throw new ArgumentNullException("MethodCallExpression"); string format;switch (){case "StartsWith":format = "({0} LIKE '{1}%')";break;case "Contains":format = "({0} LIKE '%{1}%')";break;case "EndsWith":format = "({0} LIKE '%{1}')";break;default:throw new NotSupportedException(m.NodeType + " is not supported!"); }this.Visit(m.Object);this.Visit(m.Arguments[0]);string right = this._StringStack.Pop();string left = this._StringStack.Pop();this._StringStack.Push(String.Format(format, left, right));return m;}}}ConstantSqlString泛型缓存缓存⽣成的sqlusing System;using System.Linq;namespace MyExpression{public class ConstantSqlString<T>{/// <summary>/// 泛型缓存,⼀个类型⼀个缓存/// </summary>private static string FindSql = null;/// <summary>/// 获取查询sql/// </summary>static ConstantSqlString(){Type type = typeof(T);FindSql = $"Select {string.Join(',', type.GetProperties().Select(c => $"[{}]").ToList())} from {}";}/// <summary>/// 获取查询sql+条件筛选/// </summary>/// <param name="exp"></param>/// <returns></returns>public static string GetQuerySql(string exp){return $"{FindSql} where {exp}";}}}普通多条件Expression<Func<People, bool>> lambda = x => x.Age > 5&& x.Id > 5&& .StartsWith("1") // like '1%'&& .EndsWith("1") // like '%1'&& .Contains("1");// like '%1%'ConditionBuilderVisitor vistor = new ConditionBuilderVisitor();vistor.Visit(lambda);string sql = ConstantSqlString<People>.GetQuerySql(vistor.Condition());Console.WriteLine(sql);外部参数变量string name = "AAA";Expression<Func<People, bool>> lambda = x => x.Age > 5 && == name || x.Id > 5;ConditionBuilderVisitor vistor = new ConditionBuilderVisitor();vistor.Visit(lambda);string sql = ConstantSqlString<People>.GetQuerySql(vistor.Condition());Console.WriteLine(sql);内部常量多条件Expression<Func<People, bool>> lambda = x => x.Age > 5 || ( == "A" && x.Id > 5);ConditionBuilderVisitor vistor = new ConditionBuilderVisitor();vistor.Visit(lambda);string sql = ConstantSqlString<People>.GetQuerySql(vistor.Condition());Console.WriteLine(sql);运⾏结果Select [Age],[Name] from People where ((((( [Age] > 5) AND ( [Id] > 5)) AND ( [Name] LIKE '1%')) AND ( [Name] LIKE '%1')) AND ( [Name] LIKE '%1%')) Select [Age],[Name] from People where ((( [Age] > 5) AND ( [Name] = 'AAA')) OR ( [Id] > 5))Select [Age],[Name] from People where (( [Age] > 5) OR (( [Name] = A) AND ( [Id] > 5)))七、多条件拼接⽰例1、动态拼接lambda表达式/// <summary>/// Lambda表达式拼接扩展类/// </summary>public static class Utility{/// <summary>/// Lambda表达式拼接/// </summary>/// <typeparam name="T"></typeparam>/// <param name="first"></param>/// <param name="second"></param>/// <param name="merge"></param>。
Si Expression 2快速操作指南中文Si Expression 2快速操作指南本指南介绍了Si Expression 2音频调音台的快速操作指南。
请按照以下步骤进行操作。
1.连接设备- 将音频输入设备(如麦克风、乐器)插入Si Expression 2的输入端口。
- 将音频输出设备(如扬声器、耳机)插入Si Expression 2的输出端口。
2.电源开关和启动- 打开音频调音台的电源开关。
- Si Expression 2将启动并显示主屏幕。
3.通道设置- 选择一个通道,例如通道1.- 调整增益:使用增益旋钮调整通道1的输入信号增益。
- 设置均衡器:使用均衡器控件调整通道1的音频频率响应。
4.输出设置- 选择一个输出通道,例如输出1.- 调整输出增益:使用输出增益控件调整输出通道1的音频输出级别。
- 应用效果:使用内置效果器将效果应用于输出通道1的音频。
5.路由设置- 配置输入和输出路由:使用路由矩阵来将输入信号路由到输出通道。
6.混音设置- 使用混音控制台将多个通道的音频信号混合在一起。
- 调整每个通道的音量:使用通道音量控制来调整每个通道在混音中的音量。
7.存储和回调- 使用存储和回调功能保存和调用预设设置。
- 在调音台上按下“存储”按钮,选择一个存储位置,将当前设置保存为预设。
- 通过按下“回调”按钮和选择预设位置来调用保存的预设设置。
8.其他功能- Si Expression 2还具有许多其他功能,如搭配计算机进行录音、自动混音和外部控制等。
附件:1.Si Expression 2快速操作指南(英文版):附带更详细的操作步骤和示例。
2.Si Expression 2用户手册:提供更全面的功能介绍和操作说明。
法律名词及注释:1.存储:在音频调音台中保存当前设置的功能。
2.回调:从保存的预设设置中调用并应用设置的功能。
3.输入设备:用于将音频信号输入音频调音台的设备,如麦克风、乐器。
implode的用法
implode() 函数是PHP中用来将数组元素连接成一个字符串的函数。
它的语法是,implode(separator, array)。
其中,separator是可选的,用来指定在连接数组元素时使用的分隔符,默认是空字符串。
array是必需的,表示要连接的数组。
当我们调用implode()函数时,它会将数组中的元素按照指定的分隔符连接成一个字符串,并返回该字符串。
这个函数在处理数据库查询结果、生成CSV文件等场景中非常有用。
举个例子,如果我们有一个数组$colors = array("red", "green", "blue"),我们可以使用implode()函数将数组元素连接成一个以逗号分隔的字符串,如下所示:
$colorsString = implode(",", $colors);
echo $colorsString;
上述代码将输出,red,green,blue.
需要注意的是,如果数组中的元素是对象,那么在连接时会调用对象的__toString()方法来获取字符串表示。
如果数组中的元素是数组,那么implode()函数会递归地将子数组连接成字符串。
除了implode()函数,PHP还提供了类似功能的函数,比如
join()函数,它们的功能是相同的,只是参数的顺序不同。
但是在实际开发中,一般推荐使用implode()函数,因为它更符合人们对字符串连接的直观理解。
总的来说,implode()函数是PHP中用来将数组元素连接成字符串的重要函数,能够帮助我们在实际开发中处理各种数据连接的需求。
_beginthreadex的正确用法BeginThreadEx 函数是在 Windows 操作系统中用于创建一个新线程的函数。
它提供了一种方式来创建一个运行在独立线程上的函数,并且能够传递参数给这个函数。
本文将详细介绍 BeginThreadEx 函数的正确用法,包括使用步骤和一些注意事项。
1. 引言在多线程编程中,创建新线程是一项常见的需求。
Windows 操作系统提供了多种方式来实现这一目标,而 BeginThreadEx 函数是其中之一。
通过使用BeginThreadEx 函数,我们可以创建一个新线程,并且传递参数给这个线程执行的函数。
接下来,我们将一步步了解如何正确使用 BeginThreadEx 函数。
2. 步骤在使用 BeginThreadEx 函数前,请确保已经包含了相关的头文件和链接器库。
c++include <windows.h>在开始使用 BeginThreadEx 函数之前,我们需要先定义一个线程函数。
c++DWORD WINAPI ThreadFunction(LPVOID lpParam){线程执行的代码逻辑return 0;}在以上代码中,我们定义了一个名为 ThreadFunction 的函数,它具有 DWORD 返回类型并且接受一个指向 VOID 的参数 lpParam。
在这个函数中,我们可以编写任何我们希望在线程中运行的代码逻辑。
接下来,我们使用 BeginThreadEx 函数来创建一个新线程。
c++DWORD dwThreadId;HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadFunction, lpParam, 0, &dwThreadId);在以上代码中,我们传递了以下参数给 BeginThreadEx 函数:`NULL`:安全描述符,允许使用默认的安全描述符。
`0`:栈大小,使用默认的栈大小。
csh简单语法csh简单语法csh一、变数1. 字串变数这个部分和Bourne Shell的变数一样,只不过在设定变数值时不能使用Bourne Shell的方式,而必须打:set var=value2. 数字运算基本上C Shell 没有数字变数,但C Shell 却有简单的方法处理数字运算:@ var operator expressionoperator可以是C 语言中的=, +=, -=,……,而expression则是运算式。
运算式的运算子如下:A. () 改变计算的顺序~@B. ~ 位元NOT运算@~~! 逻辑否定C.% 取馀数/ 除* 乘- 减+ 加D.>> 右移<< 左移E.> 大於< 小於>= 大於等於<= 小於等於!= 不等於== 等於F.& 位元AND运算^ 位元XOR运算| 位元OR 运算G.&& 逻辑AND|| 逻辑OR除此之外,我们也可以检验一个档案的状态,如下-n filename而-n可为下列之一-d 档案是一个目录档案-e 档案存在-f 档案为一般的档案-o 使用者拥有这个档案-r 使用者可以读取这个档案-w 使用者可以写入这个档案-x 使用者可以执行这个档案-z 档案长度为0@ count = count + 1@ flag = -e /users/cc/mgtsai/mail && -e /usr/spool/mail 3. 阵列在C Shell 中,我们可以宣告阵列变数,方式如下set var=(val1 val2 ……)而var[1]之值为val1,var[2]之值为val2……。
而$var代表整个阵列。
我们可以用$#var 来计算阵列个数,也可以用$?var 来检查某个变数是否已宣告。
4. 特殊变数$argv 和Bourne Shell的$*相似,只不过这是一个阵列。
splice方法首先,让我们来看一下splice方法的基本语法:array.splice(start, deleteCount, item1, item2, ...)。
其中,array是要操作的数组,start是要开始修改的位置,deleteCount是要删除的元素个数,item1, item2, ...是要添加到数组中的元素。
需要注意的是,splice方法会直接修改原数组,并返回被删除的元素组成的新数组。
接下来,我们来看一些具体的示例,以便更好地理解splice方法的使用。
首先,我们来看一个简单的示例,实现在数组中添加元素的功能:```javascript。
const arr = [1, 2, 3, 4, 5];arr.splice(2, 0, 6);// 现在arr变成了[1, 2, 6, 3, 4, 5]```。
在这个示例中,我们使用splice方法在数组的第三个位置(索引为2)添加了一个元素6。
可以看到,splice方法可以很方便地实现在指定位置添加元素的功能。
接下来,我们来看一个示例,实现在数组中删除元素的功能:```javascript。
const arr = [1, 2, 3, 4, 5];arr.splice(2, 1);// 现在arr变成了[1, 2, 4, 5]```。
在这个示例中,我们使用splice方法在数组的第三个位置(索引为2)删除了一个元素。
可以看到,splice方法也可以很方便地实现删除元素的功能。
最后,我们来看一个示例,实现在数组中替换元素的功能:```javascript。
const arr = [1, 2, 3, 4, 5];arr.splice(2, 1, 6);// 现在arr变成了[1, 2, 6, 4, 5]```。
在这个示例中,我们使用splice方法在数组的第三个位置(索引为2)替换了一个元素。
可以看到,splice方法也可以很方便地实现替换元素的功能。
splice用法spliceJavaScript发者经常使用的一个内置函数,它可以改变数组的内容。
splice用于添加,移除,替换和抽取数组元素的一种常用方法。
在本文中,我们将深入研究 splice语法及其用法。
Splice语法Splice语法非常简单:将你要更改的值传递给 splice数。
splice数接受三个参数,分别是要开始更改的索引,要移除或替换的值的数量,以及要添加的项。
例如,splice(0, 2, Hello world!)从数组的索引 0始移除两个元素,并在其位置插入一个新的项Hello world!”。
Splice用法以下是几个 splice常见用法:替换数组内容你可以使用 splice数来替换数组内容:例如:var names = [somebody1somebody2somebody3;names.splice(0,2,somebody4somebody5console.log(names) // [somebody4somebody5somebody3 从数组中添加新项目你可以使用 splice数来给数组添加新元素:例如:var names = [somebody1somebody2somebody3;names.splice(2,0,somebody4somebody5console.log(names) //[somebody1somebody2somebody4somebody5somebody3从数组中移除项目你可以使用 splice数来从数组中移除指定的元素:例如:var names = [somebody1somebody2somebody3;names.splice(1,1)console.log(names) // [somebody1somebody3以上就是 splice基本用法。
很明显,splice以用来改变数组的内容。
它可以用来添加,移除,替换和抽取数组元素,这使得它在JavaScript发中非常有用,因为它可以帮助我们动态改变数组内容。