ShoneSharp语言(S#)的设计和使用介绍系列(11)—“类”披炫服靓妆化成“表”
ShoneSharp语言(S#)的设计和使用介绍
系列(11)—“类”披炫服靓妆化成“表”
作者:Shone
声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/ShoneSharp。
摘要: 匿名类指类定义体(即代码块)本身,使得类也成为所谓的“一等公民”,类也可以像变量一样进行赋值定义、传递和使用。S#语言的数据类就是程序代码,数据表是该代码运行时对应的数据值,为此本文介绍了数据表、类定义和类实例化的各种使用方法,让你体验S#强大的数据和信息表达能力。
软件: S#语言编辑解析运行器13.6.31,运行环境.NET 4.0,绿色软件,单个EXE直接运行,无副作用。网盘下载链接为https://pan.baidu.com/s/1nv1hmJn
有了前述S#公式、函数以及语句的铺垫,终于进入到本系列的高潮部分介绍———S#类,为配合本文例子,请使用最新软件13.6.31版运行本文示例。
一、引言
世界很复杂,世界也很简单。站在不同角度,收获视图也不一样。前面第四章第二节已经清晰地展示S#符号解析运行视图,提到了:
S#语言开始处理的是数据,最终获得的也是数据,从而形成周而复始的闭环,最终用于实现“数据 → 信息 → 智慧”的完美进化。
S#语言的表达其实也是数据加工成信息的过程,即从没有意义的数据,变成有指定意义的数据(信息)。那么怎么表达呢?
S#第一定律:万物皆对象,对象皆引用。
S#把所有数据值都看成是一个.NET Object对象,可以表达任意数据类型的数据值,而且所有数据都是.NET引用,默认情况下后面的操作不应修改引用数据的内容,而会产生新的应用,保证数据表达或加工过程不产生副作用。
S#第二定律:程序就是树,代码即节点。
S#把程序代码本身也看成是一棵语法数据树,每个树节点对应不同的语法结构代码,可以包含运行过程生成的数据值。因此可以把树节点看成是其数据值的包装,而且树节点本身也是一种数据值,这样就会统一了程序与数据之间的关系,达到“程序即数据,数据即程序”的无缝融合。
S#第三定律:程序以类聚,数据以表分。
第二定律指出程序也是数据,而程序与数据的关系是动态映射的。在程序运行过程中程序的一个数据节点通常保持不变,但其包含的数据值却是根据上下文动态变化的,即不同实例的数据值。因此相同功能的程序代码通常写成一个数据类(简称类),对一个类进行实例化后得到的是一个数据表(简称表)。再次强调与其他语言不同,S#类是程序代码,S#表是该代码运行时对应的数据值,这就是所谓的“类”披炫服靓妆化成“表”。
S#第四定律:无名成列表,有名数据表。
用道德经的名言“无名天地之始,有名万物之母”来描述S#对数据的理解再贴合不过了。上帝创世时的世间万物还都是无名,但取名这事,还是归功于人类的聪明才智,为此人类创造了语言。同样S#语言表达一系列无名的数据集合时采用列表,而表达一系列有名的数据集合时采用的是数据表。可见命名是S#语言表达数据的关键方式,也是把数据加工成信息的必经之路。
上面就是S#语言的圣经,如果您对编程语言领域(PL,Programming Language,网上引起很多争议的王垠就是这方面的专家)有比较深入的研究,本人上述的宏观论断或许会引发您的深思或顿悟。不过不懂没关系,懵懂也很好,下面我就会逐步讲解。
二、数据表
一个无名的数据值是这样子(数值):
10
一系列无名的同类数据值是这样子(数组):
[10, 20, 30]
一系列无名的各类数据值是这样子(列表):
{'box', 10, 20, 30, true}
一系列有名的各类数据值是这样子(数据表):
(1)标准写法
{Name='box', L=, W=, H=, Visible=true}
这种表达让我们看到了盒子及其长宽高等更多的数据含义,促使原始无意义的数据加工成了有意义的信息。这就是数据表的标准写法,可用于表达包含一系列键值数据对的集合,注意与其他语言不同,数据表带有局部变量堆栈,其键就是堆栈中的变量名称,而值就是变量的数据值。
如果每个键值都是数组,那么是不是与数据库的列对应,数据表也就相当于一张数据库中的表。关系数据库的理论已经证明表的关系演算与Lambada演算的表达能力是等价的,可见数据表有多么重要了。
{
Name=['box1', 'box2', 'box3'] ,
L=[, , ] ,
W=[, ] ,
H=[, , ] ,
Visible=[true, false, true]
}
正因为数据表是如此地重要,S#语言支持很多种数据表的扩展写法:
(2)JSON写法
熟悉Javascript的同学有福了,把数据表标准写法的键名写成字符串,中间符号换成冒号,就成为JSON写法。例如:
{"Name":'box', "L":, "W":, "H":, "Visible":true}
现在JSON数据在网络上大行其道,而S#语言可以说就是JSON的超集,可以直接读取JSON,处理JSON数据简直太简单、方便和残暴了。
(3)脚本写法
熟悉脚本文件的同学有福了,把数据表标准写法去掉逗号,花括号换成括号即可简化成脚本写法。例如:
(Name='box' L= W= H= Visible=true)
这种写法没有,分隔符,由于S#把换行也看成空白,因此可以很容易直接导入外部常见的各种脚本或配置文本文件,就是加上()直接解析运行即可。这种脚本数据应用也很广泛,S#语言处理起来也非常简单、方便和残暴。
(4)YAML写法
熟悉YAML和Python的同学有福了,把数据表标准写法去掉逗号和花括号,中间符号换成冒号,加上===可扩展成YAML写法,例如:
===
Name: 'box'
Size:
L:
W:
H:
Visible: true
===
//等价于标准写法
{
Name = 'box' ,
Size = { L = , W = , H = } ,
Visible = True
}
这种写法没有,分隔符,换行缩进自动处理成不同层级的嵌套,可以省略掉好多逗号和花括号,因此表达层级数据非常整齐和简洁,这点与Python处理数据有点异曲同工之妙。S#语言处理YAML也比较简单、方便。
除此之外数据表还有很多从类实例化的写法,本文后面也会专门介绍。简单的数据表也可以看作数据库中表的一条记录,如果有很多条类似这样的记录如下:
{Name='box1', L=10, W=20, H=30, Visible=true}
{Name='box2', L=11, W=21, H=31, Visible=false}
那么说明他们都是同一类型的数据,也就是有共同的模板。这时我们可以使用数据类对他们所属的分类或模板进行抽象表达——数据类(简称类),而实际的数据记录则可以按照该类进行实例化修改成对应的数据表。无名的数据类就是匿名类,有名的数据类通常通过赋值定义或显示定义。
三、匿名类
匿名类(也叫表模板、元表或自定义数据类)指数据类定义体(即代码块)本身,可以当作变量进行传递和使用,使得类成为所谓的“一等公民”。实现方式上也是通过指向类入口的指针、地址或引用传递,在程序后面调用匿名类时则把当前程序跳转到匿名类体上执行,当然每次执行还要处理同名称变量数据值的传递和堆栈进出。
(1)匿名类公式
class 缺省数据表
数据表前加class关键字就可以定义一个匿名类,可用于变量赋值。例如:
class {Name='box', L=, W=, H=, Visible=true}
(2)继承匿名类公式
class : 基类名称 缺省数据表
如果类是从指定的基类派生而来,那么class关键字后面指定一个基类名称即可,实例化的时候是先实例化基类数据再实例化当前类的数据。例如:
class : A {Name='box', L=, W=, H=, Visible=true}
S#类通常是有名字的,上述匿名类的表达方式比较简单便捷,通常用于公式中使用,复杂的请使用下面的类定义。
四、类定义
由于类是一等公民了,因此类通常也可以像变量一样进行赋值定义。
S#有两种类定义形式,但是其类实例化方法是一样的。
(1)隐式类定义
变量名称=匿名类
这种写法最为灵活多变,可使用在任何公式或语句中。因为匿名类被看作普通数据,可以通过命名变量进行传递和使用,无论是传给其他函数作为实参调用,或是作为其他函数的返回值,都没有任何违和感觉。例如:
{
f = class {a=, b=} ,
g = f{a=} , //直接调用,g结果{a=15,b=20}
h = { a = f , b = a{b=} } //变量传递后间接调用,b结果{a=10 b=30}
}
隐式类定义可以使用在任何变量赋值公式中,而且类变量的作用域还可以用专门语法进行修改。
(2)显式类定义语句(注:只能使用在语句中)
class 类名称 缺省数据表;
class关键字显示定义一个类名,进行类变量赋值。例如:
class Test {Name='box', L=, W=, H=, Visible=true}
class 类名称 语句块
与上面类似,只不过类定义体是语句块,支持更复杂代码逻辑,这时和C#的类定义代码很像。例如:
class Test
{
var L=;
var W=;
func GetArea()
{
Return L*W;
}
}
class 类名称 : 基类名称 缺省数据表;
class关键字显示定义一个类名,进行派生类变量赋值。例如:
class Test : A {Name='box', L=, W=, H=, Visible=true}
class 类名称 : 基类名称 语句块
同样类定义体也改成语句块,可支持更复杂代码逻辑,这时和C#的派生类定义代码很像。例如:
class Test : A
{
var L=;
var W=;
func GetArea()
{
Return L*W;
}
}
五、类实例化
一个类其实就是一段代码,只要进行实例化才能转化成为数据表进行使用,这与函数必须进行调用后才能转化为数据值进行使用相类似。
假设前面上下文已定义了类型A如下:
class A { L=10, W=20, Area=L*W }
那么可以使用以下四种S#的类实例化方式,可以用于任何公式和语句中。
(1)无参数的类实例化公式
类名称 {}
直接获得类代码的运行结果即数据表,注意类实例化后时还会把类名添加到数据表中。例如:
{
Rect = class {L = , W = , Area = L * W} ,
b = Rect{} // b结果为 { Class = 'Rect', L = 10 , W = 20 , Area = 200 }
}
(2)带参数的类实例化公式
类名称 { 参数赋值系列 }
传入参数数据值并赋值给类代码中的同名变量,再运行类代码获得的结果数据表。注意如果传入参数没有找到同名变量,那么也会添加到结果数据表中,注意类实例化后时还会把类名添加到数据表中。例如:
{
Rect = class {L = , W = , Area = L * W} ,
b = Rect{L=, X=} // b结果为 { Class = 'Rect', L = 4 , W = 20 , Area = 80, X=50 }
}
(3)带子节点的类实例化公式
类名称 { 类实例化公式系列 }
运行类代码并把子节点作为Children变量附加到的结果数据表,注意类实例化后时还会把类名添加到数据表中。例如:
{
Shape = class {Name = ""} , //定义基类
Line = class : Shape {L = } , //定义线类
Rect = class : Shape {L = , W = , Area = L * W} , //定义矩形类
b = Shape //实例化Shape类(带子节点)
{
Line{ Name = "l", L = }
Rect{ Name = "r", L = }
}
}
//b的计算结果为:
{
Class = 'Shape',
Name = '' ,
Children = {
{ Class = 'Line', Name = 'l' , L = } ,
{
Class = 'Rect',
Name = 'r' ,
L = ,
W = ,
Area =
}
}
}
(4)带参数及子节点的类实例化公式
类名称 { 参数赋值系列 } { 类实例化公式系列 }
传入参数数据值给类代码中的同名变量,再运行类代码并把子节点作为Children变量附加到的结果数据表。注意如果传入参数没有找到同名变量,那么也会添加到结果数据表中,另外类实例化后时还会把类名添加到数据表中。例如:
{
Shape = class {Name = ""} , //定义基类
Line = class : Shape {L = } , //定义线类
Rect = class : Shape {L = , W = , Area = L * W} , //定义矩形类
b = Shape{ Name="l" Extend="扩展数据"} //实例化Shape类(带参数和子节点)
{
Line{ Name = "l", L = }
Rect{ Name = "r", L = }
}
}
//b的计算结果为:
{
Class = 'Shape' ,
Name = 'l' ,
Extend = '扩展数据' ,
Children = {
{
Class = 'Line' ,
Name = 'l' ,
L =
} ,
{
Class = 'Rect' ,
Name = 'r' ,
L = ,
W = ,
Area =
}
}
}
六、XML类实例化
S#还支持类似于XML的类实例化方式,与标准方式一一对应且功能等价,也可以用于任何公式和语句中。
(1)无参数的XML类实例化公式
<类名称/>
与XML相同,例如:
<Rect/>
(2)带参数的XML类实例化公式
<类名称 参数赋值系列/>
与XML相同,赋值序列中间用空白而不是逗号分隔,例如:
<Rect L=4 X=50/>
(3)带子节点的XML类实例化公式
与XML相似,但子节点的写法不同,这样便于扩展,例如:
<类名称/> { 类实例化公式系列 }
<Shape/>
{
<Line Name = "l" L = 5 />
<Rect Name = "r" L = 5 />
}
(4)带参数及子节点的XML类实例化公式
<类名称 参数赋值系列 /> { 类实例化公式系列 }
与XML相似,但子节点的写法不同,这样便于扩展,例如:
<Shape Name="l" Extend="扩展数据"/>
{
<Line Name = "l" L = 5 />
<Rect Name = "r" L = 5 />
}
七、类定义及实例化综合示例
下面给出一个有继承关系的类的语句级别,其实与C#类似,只不过S#更加关注于数据表达层面,不用进行序列化和反序列就能把数据全部计算并表达出来,用于动态扩展各类数据和信息是非常方便的。
{
class Drawing {
var Layer = '';
var Color = 'ByLayer';
var LineType = 'ByLayer';
var LineWidth = 'ByLayer';
var X = ;
var Y = ;
}
class Block:Drawing {
var Rotation = ;
var Scale = ;
var Children = [];
}
class Line:Drawing {
var Length = ;
var Angle = ;
}
class Circle:Drawing {
var Radius = ;
}
class Rectangle:Drawing {
var Width = ;
var Height = ;
}
return Drawing { Name = "图形", Author = "hjx" }
{
Line { Length = }
Circle { Radius = }
Block { Rotation = }
{
Line { Angle = }
Circle { Radius = }
}
};
}
计算结果如下:
{
Class = 'Drawing' ,
Layer = '' ,
Color = 'ByLayer' ,
LineType = 'ByLayer' ,
LineWidth = 'ByLayer' ,
X = ,
Y = ,
Name = '图形' ,
Author = 'hjx' ,
Children = {
{
Class = 'Line' ,
Layer = '' ,
Color = 'ByLayer' ,
LineType = 'ByLayer' ,
LineWidth = 'ByLayer' ,
X = ,
Y = ,
Length = ,
Angle =
} ,
{
Class = 'Circle' ,
Layer = '' ,
Color = 'ByLayer' ,
LineType = 'ByLayer' ,
LineWidth = 'ByLayer' ,
X = ,
Y = ,
Radius =
} ,
{
Class = 'Block' ,
Layer = '' ,
Color = 'ByLayer' ,
LineType = 'ByLayer' ,
LineWidth = 'ByLayer' ,
X = ,
Y = ,
Rotation = ,
Scale = ,
Children = {
{
Class = 'Line' ,
Layer = '' ,
Color = 'ByLayer' ,
LineType = 'ByLayer' ,
LineWidth = 'ByLayer' ,
X = ,
Y = ,
Length = ,
Angle =
} ,
{
Class = 'Circle' ,
Layer = '' ,
Color = 'ByLayer' ,
LineType = 'ByLayer' ,
LineWidth = 'ByLayer' ,
X = ,
Y = ,
Radius =
}
}
}
}
}
八、S#语言小结
至今为止,本系列博文把S#的基本语言特性大都介绍过了,还有一些高级特性后续博文继续讲解。不知您对S#语言有何看法?如有请把您理解的优势利弊发表在下面评论中。
总而言之,S#语言是一种基于.NET平台的面向表达的动态语言,他尽量兼收并蓄了其他语言常用的语法特性,把数据值、数组、列表、数据表、函数以及数据类全部都看做是一等公民,并通过对公式和语句两种语法基础结构的对全面支持和扩展,使得该语言化繁为简,表达能力相当出色。
声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/ShoneSharp。
软件: S#语言编辑解析运行器13.6.31,运行环境.NET 4.0,绿色软件,单个EXE直接运行,无副作用。网盘下载链接为https://pan.baidu.com/s/1nv1hmJn
ShoneSharp语言(S#)的设计和使用介绍系列(11)—“类”披炫服靓妆化成“表”的更多相关文章
- ShoneSharp语言(S#)的设计和使用介绍系列(7)— 布尔Bool及对象Object
ShoneSharp语言(S#)的设计和使用介绍 系列(7)— 布尔Bool及对象Object 作者:Shone 声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/ ...
- ShoneSharp语言(S#)的设计和使用介绍系列(1)— 开篇
ShoneSharp语言(S#)的设计和使用介绍 系列(1)- 开篇 作者:Shone 声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/ShoneSharp. 一 ...
- ShoneSharp语言(S#)的设计和使用介绍系列(4)— 入门概述
ShoneSharp语言(S#)的设计和使用介绍 系列(4)- 入门概述 作者:Shone 声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/ShoneSharp. ...
- ShoneSharp语言(S#)的设计和使用介绍系列(3)— 修炼工具
ShoneSharp语言(S#)的设计和使用介绍 系列(3)- 修炼工具 作者:Shone 声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/ShoneSharp. ...
- ShoneSharp语言(S#)的设计和使用介绍系列(2)— 掀开盖头
ShoneSharp语言(S#)的设计和使用介绍 系列(2)- 掀开盖头 作者:Shone 声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/ShoneSharp. ...
- ShoneSharp语言(S#)的设计和使用介绍系列(10)— 富家子弟“语句“不炫富
ShoneSharp语言(S#)的设计和使用介绍 系列(10)— 富家子弟“语句“不炫富 作者:Shone 声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/Sho ...
- ShoneSharp语言(S#)的设计和使用介绍系列(9)— 一等公民“函数“爱炫巧
ShoneSharp语言(S#)的设计和使用介绍 系列(9)— 一等公民“函数“爱炫巧 作者:Shone 声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/Shon ...
- ShoneSharp语言(S#)的设计和使用介绍系列(8)— 最炫“公式”风
ShoneSharp语言(S#)的设计和使用介绍 系列(8)— 最炫“公式”风 作者:Shone 声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/ShoneSha ...
- ShoneSharp语言(S#)的设计和使用介绍系列(6)— 字符串String
ShoneSharp语言(S#)的设计和使用介绍 系列(6)— 字符串String 作者:Shone 声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/ShoneS ...
随机推荐
- Java阻塞队列四组API介绍
Java阻塞队列四组API介绍 通过前面几篇文章的学习,我们已经知道了Java中的队列分为阻塞队列和非阻塞队列以及常用的七个阻塞队列.如下图: 本文来源:凯哥Java(kaigejava)讲解Java ...
- 标准库sys
sys模块的主要函数介绍,结合官方文档说明和实例.This module provides access to some variables used or maintained by the int ...
- 第三方库 正则表达式re模块
正则表通常被用来检索.替换那些符合某个模式(规则)的文本. 正则表达式通常缩写成“regex”,单数有regexp.regex,复数有regexps.regexes.regexen. 正则表达式是对字 ...
- 为物联网而生:高性能时间序列数据库HiTSDB商业化首发!
为什么80%的码农都做不了架构师?>>> 摘要: 近日,阿里云宣布高性能时间序列数据库 (High-Performance Time Series Database , 简称 H ...
- 关于通过Date.getTime()得到1970年01月1日0点零分问题验证
public static String getTimestamp_1970() throws Exception { java.text.SimpleDateFormat formater = ...
- 【XR-3】核心城市(树直径)
[XR-3]核心城市 这题真的难啊......... k个核心城市太麻烦,我们假设先找一个核心城市,应该放在哪里? \(任意取一个点,它的最远端是直径的端点.\) \(所以当这个点是直径的中点时,可以 ...
- Java常见的集合的数据结构
数据结构 数据结构__栈:先进后出 栈:stack,又称堆栈,它是运算受限的线性表,其限制是仅允许在标的一端进行插入和删除操作,不允许在其他任何位置进行添加.查找.删除等操作. 简单的说:采用该结构的 ...
- linux下在用python向文件写入数据时'\n'不起作用
网上翻看一圈,大家都说利用write写数据换行,在linux下用'\n',windows下利用'\r\n',可是尝试了一下,'\n'在windows底下可换行,在linux底下居然不起作用,最后利用' ...
- 写了shell脚本想一键启动三台虚拟机的Zookeeper,却不知道为啥总是启动不了
首先,一键启动的shell脚本是这样的 #! /bin/bash case $1 in "start"){ for i in node01 node02 node03 do ssh ...
- 【Kafka】配置文件说明
目录 server.properties producer.properties consumer.properties server.properties # broker的全局唯一编号,不能重复 ...