ShoneSharp語言(S#)的設計和使用介紹系列(11)—“類”披炫服靚妝化成“表”

来源:http://www.cnblogs.com/ShoneSharp/archive/2017/12/23/ShoneSharp-11.html
-Advertisement-
Play Games

匿名類指類定義體(即代碼塊)本身,使得類也成為所謂的“一等公民”,類也可以像變數一樣進行賦值定義、傳遞和使用。S#語言的數據類就是程式代碼,數據表是該代碼運行時對應的數據值,為此本文介紹了數據表、類定義和類實例化的各種使用方法,讓你體驗S#強大的數據和信息表達能力。 ...


 

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=10,  W=20,  H=30,  Visible=true}

 

這種表達讓我們看到了盒子及其長寬高等更多的數據含義,促使原始無意義的數據加工成了有意義的信息。這就是數據表的標準寫法,可用於表達包含一系列鍵值數據對的集合,註意與其他語言不同,數據錶帶有局部變數堆棧,其鍵就是堆棧中的變數名稱,而值就是變數的數據值。

如果每個鍵值都是數組,那麼是不是與資料庫的列對應,數據表也就相當於一張資料庫中的表。關係資料庫的理論已經證明表的關係演算與Lambada演算的表達能力是等價的,可見數據表有多麼重要了。

{

Name=['box1', 'box2', 'box3'] ,

L=[10, 11, 12] ,

W=[20, 21 22] ,

H=[30, 31, 32] ,

Visible=[true, false, true]

}

 

正因為數據表是如此地重要,S#語言支持很多種數據表的擴展寫法:

(2)JSON寫法

熟悉Javascript的同學有福了,把數據表標準寫法的鍵名寫成字元串,中間符號換成冒號,就成為JSON寫法。例如:

{"Name":'box',  "L":10,  "W":20,  "H":30,  "Visible":true}

 

現在JSON數據在網路上大行其道,而S#語言可以說就是JSON的超集,可以直接讀取JSON,處理JSON數據簡直太簡單、方便和殘暴了。

(3)腳本寫法

熟悉腳本文件的同學有福了,把數據表標準寫法去掉逗號,花括弧換成括弧即可簡化成腳本寫法。例如:

(Name='box'  L=10  W=20  H=30  Visible=true)

 

這種寫法沒有,分隔符,由於S#把換行也看成空白,因此可以很容易直接導入外部常見的各種腳本或配置文本文件,就是加上()直接解析運行即可。這種腳本數據應用也很廣泛,S#語言處理起來也非常簡單、方便和殘暴。

(4)YAML寫法

熟悉YAML和Python的同學有福了,把數據表標準寫法去掉逗號和花括弧,中間符號換成冒號,加上===可擴展成YAML寫法,例如:

===

Name: 'box'

Size:

L: 10

W: 20

H: 30

Visible: true

===

//等價於標準寫法

{

    Name = 'box'  ,

   Size = { L = 10 , W = 20 , H = 30 }  ,

   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=10,  W=20,  H=30,  Visible=true}

 

(2)繼承匿名類公式

class : 基類名稱 預設數據表

如果類是從指定的基類派生而來,那麼class關鍵字後面指定一個基類名稱即可,實例化的時候是先實例化基類數據再實例化當前類的數據。例如:

class : A {Name='box',  L=10,  W=20,  H=30,  Visible=true}

 

S#類通常是有名字的,上述匿名類的表達方式比較簡單便捷,通常用於公式中使用,複雜的請使用下麵的類定義。

四、類定義

由於類是一等公民了,因此類通常也可以像變數一樣進行賦值定義。

S#有兩種類定義形式,但是其類實例化方法是一樣的。

(1)隱式類定義

變數名稱=匿名類

這種寫法最為靈活多變,可使用在任何公式或語句中。因為匿名類被看作普通數據,可以通過命名變數進行傳遞和使用,無論是傳給其他函數作為實參調用,或是作為其他函數的返回值,都沒有任何違和感覺。例如:

{

f = class {a=10, b=20}  ,

g = f{a=15}  ,                 //直接調用,g結果{a=15,b=20}

h = { a = f , b = a{b=30} }    //變數傳遞後間接調用,b結果{a=10 b=30}

}

 

隱式類定義可以使用在任何變數賦值公式中,而且類變數的作用域還可以用專門語法進行修改。

(2)顯式類定義語句(註:只能使用在語句中)

class 類名稱 預設數據表;

class關鍵字顯示定義一個類名,進行類變數賦值。例如:

class Test {Name='box',  L=10,  W=20,  H=30,  Visible=true}

 

class 類名稱 語句塊

與上面類似,只不過類定義體是語句塊,支持更複雜代碼邏輯,這時和C#的類定義代碼很像。例如:

class Test

{

var L=10;

var W=20;

func GetArea()

{

Return L*W;

}

}

 

class 類名稱 : 基類名稱 預設數據表;

class關鍵字顯示定義一個類名,進行派生類變數賦值。例如:

class Test : A {Name='box',  L=10,  W=20,  H=30,  Visible=true}

 

class 類名稱 : 基類名稱 語句塊

同樣類定義體也改成語句塊,可支持更複雜代碼邏輯,這時和C#的派生類定義代碼很像。例如:

class Test : A

{

var L=10;

var W=20;

func GetArea()

{

Return L*W;

}

}

 

五、類實例化

一個類其實就是一段代碼,只要進行實例化才能轉化成為數據表進行使用,這與函數必須進行調用後才能轉化為數據值進行使用相類似。

假設前面上下文已定義了類型A如下:

class A { L=10,  W=20,  Area=L*W }

那麼可以使用以下四種S#的類實例化方式,可以用於任何公式和語句中。

(1)無參數的類實例化公式

類名稱 {}

直接獲得類代碼的運行結果即數據表,註意類實例化後時還會把類名添加到數據表中。例如:

{

    Rect = class {L = 10, W = 20, Area = L * W}   ,

    b = Rect{}     // b結果為 { Class = 'Rect', L = 10 , W = 20 , Area = 200 }

}

 

(2)帶參數的類實例化公式

類名稱 { 參數賦值系列 }

傳入參數數據值並賦值給類代碼中的同名變數,再運行類代碼獲得的結果數據表。註意如果傳入參數沒有找到同名變數,那麼也會添加到結果數據表中,註意類實例化後時還會把類名添加到數據表中。例如:

{

    Rect = class {L = 10, W = 20, Area = L * W}   ,

    b = Rect{L=4, X=50}      // b結果為 { Class = 'Rect', L = 4 , W = 20 , Area = 80, X=50 }

}

 

(3)帶子節點的類實例化公式

類名稱 { 類實例化公式系列 }

運行類代碼並把子節點作為Children變數附加到的結果數據表,註意類實例化後時還會把類名添加到數據表中。例如:

{

    Shape = class {Name = ""}   ,        //定義基類

    Line = class : Shape {L = 10}   ,    //定義線類

    Rect = class : Shape {L = 10, W = 20, Area = L * W}   , //定義矩形類

    b = Shape         //實例化Shape類(帶子節點)

    {

        Line{ Name = "l", L = 5 }

        Rect{ Name = "r", L = 5 }

    }

}

//b的計算結果為:

{

    Class = 'Shape',

    Name = ''  ,

    Children = {

        { Class = 'Line', Name = 'l' , L = 5 }  ,

        {

            Class = 'Rect',

            Name = 'r'  ,

            L = 5  ,

            W = 20  ,

            Area = 100

        }

    }

}

 

(4)帶參數及子節點的類實例化公式

類名稱 { 參數賦值系列 } { 類實例化公式系列 }

傳入參數數據值給類代碼中的同名變數,再運行類代碼並把子節點作為Children變數附加到的結果數據表。註意如果傳入參數沒有找到同名變數,那麼也會添加到結果數據表中,另外類實例化後時還會把類名添加到數據表中。例如:

{

    Shape = class {Name = ""}   ,        //定義基類

    Line = class : Shape {L = 10}   ,    //定義線類

    Rect = class : Shape {L = 10, W = 20, Area = L * W}   , //定義矩形類

    b = Shape{ Name="l" Extend="擴展數據"}      //實例化Shape類(帶參數和子節點)

    {

        Line{ Name = "l", L = 5 }

        Rect{ Name = "r", L = 5 }

    }

}

//b的計算結果為:

{

    Class = 'Shape'  ,

    Name = 'l'  ,

    Extend = '擴展數據'  ,

    Children = {

        {

            Class = 'Line'  ,

            Name = 'l'  ,

            L = 5

        }  ,

        {

            Class = 'Rect'  ,

            Name = 'r'  ,

            L = 5  ,

            W = 20  ,

            Area = 100

        }

    }

}

 

六、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 = '0';

        var Color = 'ByLayer';

        var LineType = 'ByLayer';

        var LineWidth = 'ByLayer';

        var X = 0;

        var Y = 0;

}  

 

    class Block:Drawing {

        var Rotation = 0;

        var Scale = 1;

        var Children = [];

} 

 

    class Line:Drawing {

        var Length = 100;

        var Angle = 45;

} 

 

    class Circle:Drawing {

        var Radius = 50;

}

 

    class Rectangle:Drawing {

        var Width = 100;

        var Height = 50;

}

 

    return Drawing { Name = "圖形", Author = "hjx" }

    {

        Line { Length = 50 }

        Circle { Radius = 30 }

        Block { Rotation = 45 }

        {

            Line { Angle = 15 }

            Circle { Radius = 80 }

        }

    };

}

 

計算結果如下:

{

    Class = 'Drawing'  ,

    Layer = '0'  ,

    Color = 'ByLayer'  ,

    LineType = 'ByLayer'  ,

    LineWidth = 'ByLayer'  ,

    X = 0  ,

    Y = 0  ,

    Name = '圖形'  ,

    Author = 'hjx'  ,

    Children = {

        {

            Class = 'Line'  ,

            Layer = '0'  ,

            Color = 'ByLayer'  ,

            LineType = 'ByLayer'  ,

            LineWidth = 'ByLayer'  ,

            X = 0  ,

            Y = 0  ,

            Length = 50  ,

            Angle = 45

        }  ,

        {

            Class = 'Circle'  ,

            Layer = '0'  ,

            Color = 'ByLayer'  ,

            LineType = 'ByLayer'  ,

            LineWidth = 'ByLayer'  ,

            X = 0  ,

            Y = 0  ,

            Radius = 30

        }  ,

        {

            Class = 'Block'  ,

            Layer = '0'  ,

            Color = 'ByLayer'  ,

            LineType = 'ByLayer'  ,

            LineWidth = 'ByLayer'  ,

            X = 0  ,

            Y = 0  ,

            Rotation = 45  ,

            Scale = 1  ,

            Children = {

                {

                    Class = 'Line'  ,

                    Layer = '0'  ,

                    Color = 'ByLayer'  ,

                    LineType = 'ByLayer'  ,

                    LineWidth = 'ByLayer'  ,

                    X = 0  ,

                    Y = 0  ,

                    Length = 100  ,

                    Angle = 15

                }  ,

                {

                    Class = 'Circle'  ,

                    Layer = '0'  ,

                    Color = 'ByLayer'  ,

                    LineType = 'ByLayer'  ,

                    LineWidth = 'ByLayer'  ,

                    X = 0  ,

                    Y = 0  ,

                    Radius = 80

                }

            }

        }

    }

}

 

八、S#語言小結

至今為止,本系列博文把S#的基本語言特性大都介紹過了,還有一些高級特性後續博文繼續講解。不知您對S#語言有何看法?如有請把您理解的優勢利弊發表在下麵評論中。

總而言之,S#語言是一種基於.NET平臺的面向表達的動態語言,他儘量兼收並蓄了其他語言常用的語法特性,把數據值、數組、列表、數據表、函數以及數據類全部都看做是一等公民,並通過對公式和語句兩種語法基礎結構的對全面支持和擴展,使得該語言化繁為簡,表達能力相當出色。

 

聲明:原創文章歡迎轉載,但請註明出處,https://www.cnblogs.com/ShoneSharp。

軟體: S#語言編輯解析運行器13.6.31,運行環境.NET 4.0,綠色軟體,單個EXE直接運行,無副作用。網盤下載鏈接為https://pan.baidu.com/s/1nv1hmJn


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • UI界面展示: 3D模型界面: 灰度分佈界面: 下麵是源程式: 下一個任務:進行邊界檢測 思路: 文中圖片 鏈接:鏈接:https://pan.baidu.com/s/1hsImLla 密碼:m2ip ...
  • 最近在學django框架,準備用django寫一個博客園的系統,並且在寫的過程中也遇到一些問題,實踐出真知,對django開發web應用方面也有了進一步的瞭解。很多操作實現都是以我所認知的技術完成的,可能存在不合理的地方(畢竟實現的方法多種多樣),基本完成後會將源碼上傳到git,也歡迎各位大神指正。 ...
  • 這次爬取的網站是糗事百科,網址是:http://www.qiushibaike.com/hot/page/1 分析網址,參數'page/'後面的數字'1'指的是頁數,第二頁就是'/page/2',以此類推。。。 一、分析網頁 網頁圖片 然後明確要爬取的元素:作者名、內容、好笑數、以及評論數量 每一個 ...
  • 題目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional roads, such that there is exactly one path between any two p ...
  • 一般Web工程通過Jenkins遠程部署到Tomcat,可以採用Maven的tomcat-maven-plugin插件進行部署。最近接觸到Spring Boot工程的部署,由於Spring Boot應用可以使用內部集成的服務容器(如Tomcat),此時無需按原來的方法進行部署。以工程asset_we ...
  • 監督學習 概念: 在有標記的樣本(labels samples)上建立機器學習 1、數據的預處理 機器學習演算法無法理解原始數據,所以需對原始數據進行預處理,常用預處理如下: 預處理主要使用了preprocessing包,所以需對該包進行導入: import numpy as np from skle ...
  • 題目描述 有一棵點數為 N 的樹,以點 1 為根,且樹點有邊權。然後有 M 個操作,分為三種:操作 1 :把某個節點 x 的點權增加 a 。操作 2 :把某個節點 x 為根的子樹中所有點的點權都增加 a 。操作 3 :詢問某個節點 x 到根的路徑中所有點的點權和。 輸入輸出格式 輸入格式: 第一行包 ...
  • luogu題面 小學奧數呵呵 在考場上40分鐘沒證出來(數學太差),運氣好看到了規律... 來一波證明: 定義 f(a,b) 表示在 gcd(a,b)==1 情況下的答案。 貝祖定理 易證:對於 gcd(c,b)==1,c > a , 有 f(c,b) = f(a,b) + (c-a)*(b-1) ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...