Ada 程序设计语言(The Ada Programming Language)[第三集]- -
第4章 记录(Record)
4.1 概述(Overview)
记录则是由命名分量(named component)组成的复合类型,即具有不同属性的数据对象的集合,和C 下的结构(structure)、Pascal 下的记录(record) 类似。Ada 的记录比它们提供的功能更强,也就是限制更少。同时记录扩展(record extension)是 Ada95 中类型扩展(继承)机制的基础,使记录的地位更加突出,关于记录扩展详见 第6章 面向对象特性,为了避免重复,本章对此不作介绍。
4.2 简单记录(Simple Record) 记录类型的一般声明如下:
typerecord_name is
record
field name 1: type 1;
field name 2: type 2;
...
field name n: type N;
end record;
record_name
如下面的例子:
typeId_Card is
record
Full_Name : String (1..15);
ID_Number : Positive;
Age : Positive;
Birthday : String (1..15);
Familiy_Address : String (1..15);
Family_telephone : Positive;
Job : String(1..10);
end record;
My_Card :Id_Card;
一个简单ID卡的记录,包含Full_Name,ID_Number,Age,Birthday,Familiy_Address,Family_telephone,Job 这些成员。
4.3 访问和设置记录(Access and Set Records)
使用记录的成员时,只需在记录和其成员之间用 “.” 隔开即可。如赋予My_Card中的变量 Full_Name 值 Jack Werlch:
My_Card.Full_Name := "Jack Welch ";
设置记录成员的值和设置数组给人感觉上有点类似,如:
My_Card := ("Jack Welch ", 19830519,45, "Jan 1st 1976 ",
"China ",8127271,"CEO ");
将 ( )中的值依次赋给My_Card 的成员。
相同的数据类型的成员一多,无疑会使人不大明了,因此也可以:
My_Card := ( Full_Name => "Jack Welch ",
ID_Number => 19830519,
Age => 45,
Birthday => "Jan 1st 1976 ",
Familiy_Address => "China ",
Family_telephone => 8127271;
Job => "CEO ") ;
上面两种表示法可以混用,但按位值在有名的值前面:
My_Card := ( "Jack Welch ",
19830519,
Age => 45,
Birthday => "Jan 1st 1976 ",
Familiy_Address => "China ",
Family_telephone => 8127271;
Job => "CEO ");
但如果为:
My_Card := ( Full_Name => "Jack Welch ",
ID_Number => 19830519,
Age => 45,
Birthday => "Jan 1st 1976 ",
Familiy_Address => "China ",
8127271;
"CEO ");
则是非法的。
如果几个相同类型的成员,赋予同一数值,也可以:
My_Card := ( Full_Name => "Jack Welch ",
ID_Number | Family_telephone => 19830519,
Age => 45,
Birthday => "Jan 1st 1976 ",
Familiy_Address => "China ",
Job => "CEO ");
上例我们假设 ID_Number 和 Family_telephone 值是一样的,为19830519,不同成员间用 | 隔开。
记录类型有时在声明也需要默认值:
typeId_Card is
record
Full_Name : String (1..100) := "Jack Welch ",
ID_Number : Positive := 19830519,
Age : Positive := 45,
Birthday: String (1..20) := "Jan 1st 1976 ",
Familiy_Address :String (1..100):= "China ",
Family_telephone :Positive := 8127271;
Job : String(1..10) := "CEO ");
end record;
My_Card :Id_Card;
将 Jack Welch 的资料当作了 Id_Card 类型的默认值,My_Card 无须赋值,在声明时已经有了前几个例子中所赋的值。
声明常量记录如下:
My_Card :constant Id_Card := ( Full_Name => "Jack Welch ",
ID_Number => 19830519,
Age => 45,
Birthday => "Jan 1st 1976 ",
Familiy_Address => "China ",
Family_telephone => 8127271;
Job => "CEO ";)
和创建其它类型的常量类似,只需在该记录类型前添个 constant。
4.4 变体记录 (Variant Record)
在讲变体记录前,先介绍一下记录判别式(record discriminant)的概念。判别式(discriminant)以前没接触过,这里先简单提一下它的定义:一个复合类型(除了数组)可以拥有判别式,它用来确定该类型的参数(具体参见 RM95 3.7 Discriminant)。也就是说,一个复合类型创建时可以有一些参数,在接下去声明该类型的变量时,可以通过那些参数的值来改变变量初始化时所占用内存大小、成员数量、取值等等。这一节以及下一节的无约束记录(unconstrained record)的内容都在记录判别式的范围内,至于其它复合类型将在以后讲述。
变体记录,即它的一些成员存在与否取决于该记录的参数。如我们将 Id_Card 这个记录类型扩充一下:
typeId_Card (Age : Positive := 1) is
record
Full_Name : String(1..15);
ID_Number : Positive;
Birthday : String(1..15);
Familiy_Address : String(1..15);
Family_telephone : Positive;
Job : String(1..10);
case Age is
when 1 .. 18 => School_Address : String(1..15);
when 19 .. 60 => Monthly_Income : Integer;
Working_Address: String(1..15);
when others => null; -- 如果 Age 的值不属于 1..60,成员不改变
end case;
end record;
My_Card : Id_Card ;
Your_Card: Id_Card (Age => 20);
上例中,case Age ... end case 是变体部份,当 Age 值在 1..18 时,动态创建成员 School_Address;当 Age 值在 19..60 时,动态创建成员 Monthly_Income,Working_Address;当 Age 不在 1..60 时,数据成员不改动。在声明判别式时一般应赋予一个默认值,如上例 Age 的默认值为 1 ,这样声明变量 My_Card 时不带参数也可以,默认参数为 1。但如果 Age 没默认值,上例中的 My_Card 声明是非法的。
因此,记录 My_Card 有 Full_Name,ID_Number,Birthday,Familiy_Address,Family_telephone, Job,School_Address这些成员,因为 Age 默认为 1; 记录 Your_Card 中 Age 值为 20,因此有 Full_Name,ID_Number,Birthday,Familiy_Address,Family_telephone, Job, Monthly_Income,Working_Address 这些成员。
最后注意一下,变体部份要在记录类型声明的底部,不能在 Job 或其他成员前面---变体记录的变量大小是不定的。
4.5 无约束记录(Unconstrained Record) 上面的记录都是受限定的,如 创建 My_Card 后,它的判别式无法再被改动,Monthly_Income,Working_Address这些成员也无法拥有。但如果 ID_Card 的判别式有了初使值,则还有办法使记录动态改变。
如:
type Id_Card (Age : Positive := 1) is
record
Full_Name : String(1..15);
ID_Number : Positive;
Birthday : String(1..15);
Familiy_Address : String(1..15);
Family_telephone : Positive;
Job : String(1..10);
case Age is
when 1 .. 18 => School_Address : String(1..15);
when 19 .. 60 => Monthly_Income : Integer;
Working_Address: String(1..15);
when others => null;
end case;
end record;
My_Card : Id_Card ;-- 以上和上一节的例子一样
....
begin
...
My_Card := (17, "Jack Welch ", 19830519, "Jan 1st 1976 ", "China ",8127271,
"CEO ","Shanghai ");
record
Full_Name : String(1..15);
ID_Number : Positive;
Birthday : String(1..15);
Familiy_Address : String(1..15);
Family_telephone : Positive;
Job : String(1..10);
case Age is
when 1 .. 18 => School_Address : String(1..15);
when 19 .. 60 => Monthly_Income : Integer;
Working_Address: String(1..15);
when others => null;
end case;
end record;
My_Card : Id_Card ;-- 以上和上一节的例子一样
....
begin
...
My_Card := (17, "Jack Welch ", 19830519, "Jan 1st 1976 ", "China ",8127271,
"CEO ","Shanghai ");
end
赋值的时候就有了点特殊。My_Card 在程序内部赋值,但与常规赋值不同,它的第一个值是判别式的值,后面才是成员的值---成员数量按照判别式的值动态改变,上例就多了一个 School_Address 成员。这种情况下,编译器会分配给 My_Card 可能使用的最大内存空间。因此将下句接在上句后面:
My_Card := (17, "Jack Welch ", 19830519, "Jan 1st 1976 ", "China ",8127271,
"CEO ", 78112 ,"Shanghai ");
也是可行的。
上面一些记录的例子并不好,成员的数据类型太简单(像生日的数据类型,一般是年月日做成员的一个记录),字符串类型太多,手工赋值的话还要数一下有几个字符,实际中也很少这样的用法,一般还是用函数来赋值。这点请注意一下。
4.6 判别式的其它用途判别式的另一个用途是动态决定其成员长度,如:
typeBuffer (Size:Integer) is
record
High_Buffer(1..Size);
Low_Buffer(1..Size);
end record;
第5章 控制结构(Statement)5.1 概述(Overview)
在 Ada 子程序的 “is”和“end”之间,是一组有序语句,每句用双引号 ;结束。这些语句大致可分成三种控制结构:顺序结构,选择结构,循环结构----如果按照前辈们辛辛苦苦的证明:任何程序都可以只由这三种结构完成。以前我们见过的简单程序都是顺序结构,本章里会介绍一下 Ada 里选择结构的if、case 语句和循环结构的 loop 语句及其变种,并介绍顺序结构中以前没讲过的 null 和块语句(block statement),最后是比较有争议的 goto 语句---好像每本教科书上都骂它,说它打破了程序的良好结构。控制结构是一门老话题,Ada95 对它也没作多大改动,语法上和其它语言还是很接近的,但可读性好一点,所有控制结构后都以"end something"结束。
5.2 if 语句(if statement)
if 语句判断一个条件是否成立,如果成立,则执行特定的语句,否则跳过这些语句。一般格式如下:
ifcondition then
statements
end if;
当 condition 的值为 True 时,则执行 statements,否则跳过 statements,执行“end if”后面的语句。
如果当 condition 为 False 也要执行特定语句,则用下面的格式:
ifcondition then
statements
else
other statements
end if;
这样当条件不成立时,执行other statement,而不是跳过 if 结构。
下面一种格式是为了多个条件判断而用,防止 if 语句过多:
ifcondition then
statements
elsif condition then
other statements
elsif condition then
more other statements
else
even more other statements
end if;
使用 elsif 的次数没有限制,注意 elsif 的拼写----不是elseif。在这里需要注意一下 condition 的值,一定要为布尔型,不像 C 里面,随便填个整数也没事。
下面以简单的一个例子来解释一下 if 语句:
000 -- filename: ifInteger.adb
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
003 procedure testrange is
004 Var : Integer;
005 begin
006 Put ("Enter an Integer number to confirm its range:");
007 Get (Var);
008 if Var in Integer'First .. -1 then
009 Put_Line ("It is a negative number");
010 elsif Var in 1 .. Integer'Last then
011 Put_Line ("It is a positive number");
012 else
013 Put_Line ("It is 0");
014 end if;
015 end testrange;
[007] 输入值 Var;[008]-[014]的语句都是测试 Var 的范围,如是负数则输出"It is a negative number",正数输出"It is a positive number",为0则输出"It is 0",以上3种情况如果都没产生,则是因为输入值非 Integer 类型或输入值过大,从而产生异常。
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
003 procedure testrange is
004 Var : Integer;
005 begin
006 Put ("Enter an Integer number to confirm its range:");
007 Get (Var);
008 if Var in Integer'First .. -1 then
009 Put_Line ("It is a negative number");
010 elsif Var in 1 .. Integer'Last then
011 Put_Line ("It is a positive number");
012 else
013 Put_Line ("It is 0");
014 end if;
015 end testrange;
[007] 输入值 Var;[008]-[014]的语句都是测试 Var 的范围,如是负数则输出"It is a negative number",正数输出"It is a positive number",为0则输出"It is 0",以上3种情况如果都没产生,则是因为输入值非 Integer 类型或输入值过大,从而产生异常。
5.3 case 语句(case Statement)
如果所要判断的变量有多种可能,并且每种情况都要执行不同的操作,if 语句很显然繁了一点,这时就使用 case 语句,格式为:
caseexpression is
when choice1 => statements
when choice2 => statements
. . .
when others => statements
end case;
判断 expression 的值,如符合某项choice,则执行后面的statement,如果全都不符合时,就执行 others 后的语句。choice 的值不能相同。when others 也可以没有,但不推荐这样做,以免有没估计到的情况产生。因此上例也可改成:
000 -- filename: ifInteger.adb
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
003 procedure testrange is
004 Var : Integer;
005 begin
006 Put ("Enter an Integer number to confirm its range:");
007 Get(Var);
008 case Var is
009 when Integer'First .. -1 =>
010 Put_Line ("It is a negative number");
011 when 1 .. Integer'Last =>
012 Put_Line ("It is a positive number");
013 when others =>
014 Put_Line ("It is 0");
015 end case;
016 end testrange;
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
003 procedure testrange is
004 Var : Integer;
005 begin
006 Put ("Enter an Integer number to confirm its range:");
007 Get(Var);
008 case Var is
009 when Integer'First .. -1 =>
010 Put_Line ("It is a negative number");
011 when 1 .. Integer'Last =>
012 Put_Line ("It is a positive number");
013 when others =>
014 Put_Line ("It is 0");
015 end case;
016 end testrange;
与前面的例子完全等效。
5.4 loop 语句(loop Statement)
很多情况下,我们要反复执行同一操作,无疑这时要使用循环结构。循环结构除了最简单的loop语句,还有其变种for 和while语句。
最简单的loop语句格式为:
loop
statements
end loop;
当要退出该循环时,使用 exit 或 exit when 语句。exit表示直接退出该循环,exit when则在符合 when 后面的条件时再退出。再将testrange 改动一下,来了解loop和exit语句。
000 -- filename: ifInteger.adb
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
003 procedure testrange is
004 Var : Integer;
005 begin
006 loop
007 Put ("Enter an Integer number to confirm its range:");
008 Get(Var);
009 case Var is
010 when Integer'First .. -1 =>
011 Put_Line ("It is a negative number");
012 when 1 .. Integer'Last =>
013 Put_Line ("It is a positive number");
014 when others =>
015 Put_Line ("It is 0");
016 end case;
017 exit when Var = 0;
018 end loop;
019 end testrange;
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
003 procedure testrange is
004 Var : Integer;
005 begin
006 loop
007 Put ("Enter an Integer number to confirm its range:");
008 Get(Var);
009 case Var is
010 when Integer'First .. -1 =>
011 Put_Line ("It is a negative number");
012 when 1 .. Integer'Last =>
013 Put_Line ("It is a positive number");
014 when others =>
015 Put_Line ("It is 0");
016 end case;
017 exit when Var = 0;
018 end loop;
019 end testrange;
上例循环输出"Enter an Integer number to confirm its range:",要求输入一个整数;当输入值为0时,输出"it is 0",再退出。
5.5 for 循环(for loop)
for 循环只是loop的变种,格式如下:
forindex in [reverse] range loop
statements;
end loop;
*reverse 是可选的.
注意一下,index 是for循环中的局部变量,无需额外声明,只需填入一个合法的标识符即可,在for循环内,不能修改index的值。index的值一般情况下是递增加1,如 for i in 1..100,i的初值为1,每循环一次加1,直至加到100,循环100次结束;有时也需要倒过来,如i初值为100,减到1,则为 for i in reverse 1..100。但range中较大值在前则该循环不进行,如 for i in [reverse] 100..1,循环内语句会略过---即变成了空语句。
仍旧是通过修改testrange来了解for:
000 -- filename: ifInteger.adb
如果不输入0,在输入10次整数后,该程序会自动结束。
5.6 while 循环 (while loop) while 循环则在某条件不成立时结束循环,其格式为:
whilecondition loop
statements
end loop;
condiotion 和 if 语句中的 condition 一样,都要求为布尔值,在其值为 False 时,循环结束。
还是老套的testrange:
000 -- filename: ifInteger.adb
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
003 procedure testrange is
004 Var : Integer;
005 begin
006 while Var /= 0 loop
007 Put ("Enter an Integer number to confirm its range:");
008 Get(Var);
009 case Var is
010 when Integer'First .. -1 =>
011 Put_Line ("It is a negative number");
012 when 1 .. Integer'Last =>
013 Put_Line ("It is a positive number");
014 when others =>
015 Put_Line ("It is 0");
016 end case;
017 end loop;
018 end testrange;这里取消了exit when语句,由while语句来检测Var的值。当Var值为0时,循环结束。
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
003 procedure testrange is
004 Var : Integer;
005 begin
006 while Var /= 0 loop
007 Put ("Enter an Integer number to confirm its range:");
008 Get(Var);
009 case Var is
010 when Integer'First .. -1 =>
011 Put_Line ("It is a negative number");
012 when 1 .. Integer'Last =>
013 Put_Line ("It is a positive number");
014 when others =>
015 Put_Line ("It is 0");
016 end case;
017 end loop;
018 end testrange;这里取消了exit when语句,由while语句来检测Var的值。当Var值为0时,循环结束。
5.7 null 语句(null Satement)
null 语句所做的事就是不做事,大部份情况下就等于没写;但在一些情况下,还是有其作用,如 if var > 0 then null end if,如果没有 null,则属于语法错误,缺少了语句。因此 null 用在语法上要求必须有语句,但又不想让程序干什么事的时候。
5.8 块语句(Block Statement) 块语句(block statement),就是以一组语句为单位,当作一个独立的块,也常用在循环中,格式为;
identifier:
[declare]
begin
statements
end indentifier;
declare
Swap:
declare
Temp :Integer;
begin
Temp := V; V:=U; U:=Temp;
end Swap;
其中的Temp为局部变量,Swap 外的语句无法访问它,Temp也可写成Swap.Temp,以此从形式上区分局部变量和全局变量。块语句的用法,还是通过实例来讲解方便:000 -- filename: swap.adb
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
003 procedure Swap is
004 V:Integer := 1;
005 U:Integer := 2;
006 begin
007 PutVU1:
008 begin
009 Put("V is:"); Put(V); New_Line;
010 Put("U is:"); Put(U); New_Line;
011 end PutVU1;
012 Swap:
013 declare
014 Temp :Integer;
015 begin
016 Temp := V; V:=U; U:=Temp;
017 end Swap;
018 Put_Line ("After swap");
019 PutVU2:
020 begin
021 Put("V is:"); Put(V); New_Line;
022 Put("U is:"); Put(U); New_Line;
023 end PutVU3;
024 end Swap;
通过上面的例子,大家可能感觉没什么意思,块结构可有可无---反正还是按语句的先后顺序执行。但如果它用在循环结构中,则还有点用处:
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
003 procedure Swap is
004 V:Integer := 1;
005 U:Integer := 2;
006 begin
007 PutVU1:
008 begin
009 Put("V is:"); Put(V); New_Line;
010 Put("U is:"); Put(U); New_Line;
011 end PutVU1;
012 Swap:
013 declare
014 Temp :Integer;
015 begin
016 Temp := V; V:=U; U:=Temp;
017 end Swap;
018 Put_Line ("After swap");
019 PutVU2:
020 begin
021 Put("V is:"); Put(V); New_Line;
022 Put("U is:"); Put(U); New_Line;
023 end PutVU3;
024 end Swap;
通过上面的例子,大家可能感觉没什么意思,块结构可有可无---反正还是按语句的先后顺序执行。但如果它用在循环结构中,则还有点用处:
Main_Circle:
begin
loop
statements;
loop
statements;
exit Main_Circle when Found;--* 如果 Found 为 True,则跳出 Main_Circle,而不是该句所在的小循环
statements;
end loop;
statements;
end loop;
end Main_Circlel;这样就能跳出一堆嵌套循环,接下去执行的语句都在跳出的循环后面。
begin
loop
statements;
loop
statements;
exit Main_Circle when Found;--* 如果 Found 为 True,则跳出 Main_Circle,而不是该句所在的小循环
statements;
end loop;
statements;
end loop;
end Main_Circlel;这样就能跳出一堆嵌套循环,接下去执行的语句都在跳出的循环后面。
5.9 Goto语句(Goto Statement) goto 语句能直接跳到程序的某一处开始执行,使程序结构松散很多,有关编程的教材基本上将它作为碰都不能碰的东西。但在处理异常情况中,goto 还是很方便的---并被有些权威人士推荐;只要别滥用就可以了。Ada 里goto语句格式为:
<<Label>>
statements;
goto Label;
如将上例改为:
000 -- filename: swap.adb
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
003 procedure Swap is
004 V:Integer := 1;
005 U:Integer := 2;
006 begin
007 <<restart>>
008 PutVU1:
009 begin
010 Put("V is:"); Put(V); New_Line;
011 Put("U is:"); Put(U); New_Line;
012 end PutVU1;
013 Swap:
014 declare
015 Temp :Integer;
016 begin
017 Temp := V; V:=U; U:=Temp;
018 end Swap;
019 Put_Line ("After swap");
020 PutVU2:
021 begin
022 Put("V is:"); Put(V); New_Line;
023 Put("U is:"); Put(U); New_Line;
024 end PutVU2;
025 goto restart;
026 end swap;
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
003 procedure Swap is
004 V:Integer := 1;
005 U:Integer := 2;
006 begin
007 <<restart>>
008 PutVU1:
009 begin
010 Put("V is:"); Put(V); New_Line;
011 Put("U is:"); Put(U); New_Line;
012 end PutVU1;
013 Swap:
014 declare
015 Temp :Integer;
016 begin
017 Temp := V; V:=U; U:=Temp;
018 end Swap;
019 Put_Line ("After swap");
020 PutVU2:
021 begin
022 Put("V is:"); Put(V); New_Line;
023 Put("U is:"); Put(U); New_Line;
024 end PutVU2;
025 goto restart;
026 end swap;
快到程序结尾时,又返回到开头<<restart>>处,因此成了无限循环。goto语句在 Ada 里的限制还是挺多的,如不能跳到if,case,for,while里面和其所在子程序外。
是可选的,如:
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
003 procedure testrange is
004 Var : Integer;
005 begin
006 for i in 1..10 loop
007 Put ("Enter an Integer number to confirm its range:");
008 Get(Var);
009 case Var is
010 when Integer'First .. -1 =>
011 Put_Line ("It is a negative number");
012 when 1 .. Integer'Last =>
013 Put_Line ("It is a positive number");
014 when others =>
015 Put_Line ("It is 0");
016 end case;
017 exit when Var = 0;
018 end loop;
019 end testrange;
这样 Buffer 两个成员的大小就取决于 Size 值,在文本处理中这种用法还是挺好的。; 是记录类型的名称,一大堆 filed name 是记录的成员名称,紧跟其后的是该成员的数据类型。 001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
003 procedure testrange is
004 Var : Integer;
005 begin
006 for i in 1..10 loop
007 Put ("Enter an Integer number to confirm its range:");
008 Get(Var);
009 case Var is
010 when Integer'First .. -1 =>
011 Put_Line ("It is a negative number");
012 when 1 .. Integer'Last =>
013 Put_Line ("It is a positive number");
014 when others =>
015 Put_Line ("It is 0");
016 end case;
017 exit when Var = 0;
018 end loop;
019 end testrange;
职场 休闲 程序语言 编程语言
0
收藏
上一篇:Ada 程序设计语言(The A... 下一篇:Ada 程序设计语言(The A...
推荐专栏更多

微服务技术架构和大数据治理实战
大数据时代的微服务之路
共18章 | 纯洁微笑
¥51.00 669人订阅
订 阅

基于Python的DevOps实战
自动化运维开发新概念
共20章 | 抚琴煮酒
¥51.00 431人订阅
订 阅
猜你喜欢
我的友情链接 挂起C++,开始学习使用D语言 Java线程:线程的调度-休眠 我们不得不面对的中年职场危机 职场终极密籍--记我的职业生涯 用光影魔术手制作一寸照片(8张一寸) 我的IT职场生涯: 毕业4年,月薪过万 Linux关闭休眠和屏保模式 年薪从0到10万-我的IT职场经验总结 Windows7删除休眠文件hiberfil.sys节省大量C盘空间 致IT同仁 — IT人士常犯的17个职场错误 “跳槽加薪”现象,无奈的职场规则 智能合约编程语言-solidity快速入门(下) Android中适配器的notifyDataSetChanged()为何有时不刷新 如何在Spring Boot中使用Hibernate Natural ID 从hook开始聊聊那些windows内核数据结构 Scala的actor 正则性能调优 windows下kafka+ELK的日志系统 Nginx下,请求本机另外Host很慢


扫一扫,领取大礼包
0
分享
hagejid 
转载于:https://blog.51cto.com/hagejid/74843
Ctrl+Enter 发布
发布
取消