Toit编程语言

2021-03-07 11:27:30

此QuickStart指南由Ruby在二十分钟内启发。它假设您已经在计算机上安装了待机。

Toit是一种面向对象的编程语言,用于物联网。 Toit语言具有以下理想的属性:

本地安装Toit伴随着直接从命令行运行小程序的支持。如果您将以下代码放在名为hello.toit的文件中

刚才发生了什么? Toit命令行工具读取您的源代码(hello.toit),并开始从您定义的主要方法运行它。主要方法包括在方法声明行主要下面的所有缩进陈述: Toit是基于Python的缩进,所以您添加到程序的空格很大。

一旦程序运行,它将打印你好世界!在你的终端里。这是因为hello.toit中唯一的语句是一种方法调用,在其中使用单个参数调用日志方法,它是要记录的字符串(在这种情况下,打印到终端)。如果您希望从程序中输出多行,您可以将其更新为:

如果你想说"你好"很多没有让你的手指都累了?您应该定义另一个方法:

调用anit中的方法与提及其名称一样简单。如果该方法不采用任何您需要的参数。

如果我们想向一个人打招呼,而不是全世界的话怎么办?只是重新定义嗨,以姓名为论据。

这样,嗨是一种采用单个参数的方法。我们可以从主要的使用:

什么是$名称位?这是一个and#39;在字符串中插入某物的方式。它被称为字符串插值。 $后将$ in the string(如果它不是一个),然后替换为此点的外弦。您还可以使用它来确保某人的名称已正确修剪,因此忽略了导致和尾随空格:

这样,我们在将其插入外部字符串之前调用名称字符串上的TRIM方法。如果我们打电话给Hi" Lars"我们仍然得到熟悉的问候你好lars!而且不是hello lars!。您可以在字符串中的名称中添加括号。在字符串中的表达式表达式,以使其更清晰地属于外部字符串的部分:

也许你已经发现了我们前进,并在上面的代码中添加了一个其他诀窍?我们为名称参数添加了一个默认值,因此如果在您调用HI时未提供姓名,我们使用默认名称"世界"现在我们可以尝试:

如果我们想要一个真正的问候人,那么一个记得你的名字,并欢迎你并尊重你。您可能希望为此使用对象。让我们创建一个问候课:

Class Chender:name:= null构造函数.name ="世界&#34 ;: say_hi:log"嗨$ name.trim!" say_bye:log"再见$ name.trim,很快回来。"

这里的新关键字是类。这定义了一个名为Chender的新类以及该类的一系列方法。特别注意方法构造函数。在:and构造函数方法之后没有任何缩进线路,因此构造函数没有陈述:

这是一个构造函数,它定义了如何从类构造对象。它说,班级问候人员采用单个参数(姓名),但是。对.name参数的前缀实际上告诉我们名称立即存储为问候语对象的字段。该字段的定义在构造函数之上,使用:=语法。

字段参数.Name仍然存在默认值,因此如果我们不通过名称,问候会迎接世界。

在接下来的两条线上引入了Say_hi和Say_Bye方法。这些方法都有一个单一的语句,所以我们可以将它们保持在一行上。 say_hi和say_bye方法都使用它们调用的对象中的名称字段。只需提及它们(名称)即可在方法的类中引用字段。

我们简单地通过提及构造函数,问候语来创建一个对象。问候对象记得名称并为两个单独的问候语使用它。如果我们运行此操作,我们会得到以下输出:

如果您想从问候获取名称,可以通过调用它的名称方法来询问问候语:

这将显示你的海伦娜如何?。几乎整齐,对吧?不幸的是,这个名字并没有像我们预期的那样修剪。让我们解决这个问题!

正如您刚才所见,对象上的字段介绍具有相同名称的方法。如果你想隐藏来自外界的领域,你可以让它私下。按照约定,以下划线(_)结尾的方法和字段是私有的,不应该从外部触摸:

这删除了来自问候人员的名称方法,但如果我们真的想要从外部访问名称,我们可以重新引入与以前相同的含义的吸气剂。

Class Chender:name_:= null构造函数.name_ ="世界":name:return name_ say_hi:log"嗨$ name_.trim!" say_bye:log" bye $ name_.trim很快回来。"

在这里,我们使用新的关键字返回指定方法返回的值。我们可以使其在过程中稍微有趣并修剪它:

通过这种方式,访问外部的名称也得到了修剪,我们可以避免重复调整调整:

Class Chender:name_:= null构造函数.name_ ="世界":respend name_.trim say_hi:log"嗨$名称!" Say_Bye:log"再见,很快回来。"

你应该看看你是如何erik的?在主要内部,我们将发祝器存储在局部变量(问候语)中,以便我们能够继续引用相同的对象。您可以将其视为一种为特定对象提供仅在主要方法内有效和有用的名称的方法。

就像引入成员变量一样,我们可以在方法中使用:=语法和函数,如主介绍局部变量。

这个问候者并不是那么有趣,它只能一次处理一个人。如果我们有某种巨大的兆头,可以迎接世界,一个人或整个人名单?让我们试着建立这一点。我们将从班级定义开始:

所以Megagreeter对象有一个名称列表。名称字段初始化为空列表([])。 Megagreeter构造函数的正文将给定名称参数添加到名称列表的末尾。请注意,这与使用自动分配给名为name的字段的.name参数不同。 Mega Breeters Don' t有一个单个名称和没有名称字段,所以这里的名称只是我们可以在构造函数的正文中使用的普通参数。总而言之,这段代码:

//给每个人都说嗨的问候人.Class Megagreeter:名称:= []构造函数名称="世界&#34 ;: names.add名称say_hi://单独迎接每个人! names.do:log" hello $ wit!" Say_Bye:Everyal:= names.join&#34 ;," Log"再见,每个人都会回来。 greeter.names.add"卡斯珀" greeter.names.add" rikke" Greeter.say_hi greeter.say_bye.

$ toit执行hello.toithello世界!再见世界,很快回来.Hello World!你好Lars!你好Kasper!你好rikke!再见世界,Lars,Kasper,Rikke很快回来。

不是源文件中的所有内容都意味着Toit编译器运行。有时,只要添加解释与您的代码有关的有趣事物的评论很好。在最后一节中的示例中,有几个单行评论:

此类评论从//开始,并告诉系统忽略其余行。

您已经看到使用缩进来为您的代码提供分层结构。一般结构是之后:如果它适合一行,可以拥有一个构造:

或者您可以在以下方式添加换行符:并让相对于外部构造缩进的以下行是一系列内部构造:

对于方法,我们经常将内部构建体称为方法或方法的身体的陈述。内部构建体的优选压痕是两个空间。

对于一个类,在类声明行下缩进的所有内容都属于该类。我们称之为课程成员:

对于类中的方法,它们中的语句进一步嵌套(两个空格),而不是类成员:

类Megagreeter://类成员start // ... say_hi://方法body start // ... //方法正端// ... //类成员结束

让我们返回Megagreeter示例,并查看构造结构块的另一个地方。在May_hi方法中,我们要在名称列表中调用日志。我们可以通过调用names.do来完成此操作,并提供我们希望使用块结构为每个元素运行的语句列表:

在这里,该声明在单行上,因此无需使用缩进。使用名称时,可以在所有列表中提供的方法,它包含从列表中包含单个元素的特殊变量。如果名称列表中有5个元素,我们将调用log 5次产生5行输出行。

您可以通过修改和运行下面的示例来使用列表中的方法:

主题:列表:= ["马&#34 ;,#34;鱼&#34 ;,#34;萝卜&#34 ;,"狒狒" ]日志"列表中有$(list.size)元素" log"他们在这里:" list.do:log"元素= $" log"他们在这里(分类):" list.sort list.do:log"元素= $"

在构建字符串时非常有用的列表的方法之一是加入。它通过加入部分并在它们之间添加分隔符来生成字符串列表中的字符串。我们在Megagreeter示例中使用它来生成单行输出的单个逗号分隔的名称列表:

也许你并不总是想说"你好&#34 ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

它产生输出:但是,在呼叫网站上可能不清楚参数" kaixo"是的。我们可以使用名为Arguit清单更清楚:

fib n:如果n< = 1:返回n返回(fib n-1)+(fib n-2)主:log"第10个fibonnaci号码是$(fib 10)"

这定义了一个名为fib的顶级函数,这不是任何类的成员。 (我们已经看到了主要的,这是一个特殊名称的顶级函数。)

FIB功能是递归,调用自身,也使用一些新功能。 IF语句是从其他语言中众所周知的。通过拍摄表达和有条件地评估块来工作。与其他块一样,我们可以使用缩进到组多行。

Toit还具有通常的infix运算符阵列,+, - ,*,/,%等,以及关系算子< =,>> =,==和!=。操作员优先于函数参数更高,因此我们必须在括号中对呼叫进行分组以获得所需的行为。高优先级是对递归调用FIB工作的论据。我们可以传统地将其间隔开,并有相同的效果:FIB N:如果n< = 1:返回n返回(fib n - 1)+(fib n - 2)

这是计算fibonnaci的非常缓慢的方式,我们可以用一个简单的循环做到这一点:

FIB2 N:S1:= 0 S2:= 1 n.repeat:S3:= S1 + S2 S1 = S2 S2 = S3返回S1

在这里,我们正在使用数字的重复方法,该方法运行给定次数的块。喜欢做方法,有一个魔法变量,它给出了迭代号码:

重复方法简单而有效,但有时我们需要更灵活的东西,为此我们有众所周知的次数和陈述:

//打印小于n.print_odd_numbers n的奇数:i:= 1;我< n; i + = 2:如果Collat​​z猜想是真的,则返回log i //返回.collat​​z n:n> 1:如果n%2 == 0:n = n / 2其他:n = n * 3 + 1

Class Megagreeter:名称:= []标题:= {:}构造函数:添加名称标题:names.add名称标题[name] = title say_hi://单独迎接每个人!名称.Do:log"你好,$ titles [它] $它!"主要:问候:= megagreeter greeter.add" lars" "先生。" Greeter.add" rikke" "博士。" Greeter.add"Günter" "赫尔教授Doktor Doktor" Greeter.say_hi.

在这里,我们使用HashMap来为每个名称存储适当的标题。空映射由{:}和我们使用[]来访问每个键的值。空集是{},我们已经遇到了空列表[]。查找语法[]还在列表上工作,所以而不是'做'我们可以使用的方法:

//按1到10的数字,每行一个数字.10.repeat:log it + 1 //打印每行的元素.my_list.do:log it

在句子上,它们看起来像是那样的语言,如果和为此,它们实际上是在列表和整数类上的完美正常方法:

类列表:// ... Do [块]:size.repeat:block.call这个[它]类整数:// ...重复[块]:对于i:= 0;我<这; i ++:block.call我

它们正在使用称为块的功能。这些是代码的片段,可以将堆栈传递为方法和函数的参数。在呼叫网站,我们在块中与冒号,' :',并且在函数定义,我们将参数名称与方括号,&#39围绕; []'通常,有一个块参数,它处于最终位置,它被称为块。

每次运行时,块都可以返回值。这例如在列表上的滤波器方法中使用。

//获取一个单词列表,只返回一个只有5个字符或更少字符的//单词的新列表:返回lock.filter:it.size< = 5

筛选方法在原始列表中的每个元素调用块,et.size< = 5,并返回仅包含短字的新列表。

请注意,块中没有返回语句。一个块将返回最后一个语句的值,以通过block.call调用它。在这种情况下,只有一个语句,这是it.size< = 5的boolean表达式。

如果在块中使用return关键字,则它从写入的语法函数或方法返回它。通常这会表现得像你的期望:

wheres_walter列表:list.do:如果它是.starts_with" walter&#34 ;:返回它返回nullmain:log(wheres_walter [" ib michael"" walter white&#34 ;, "玛丽居里"])

return关键字在传递给do方法的块中。当以&#34开头的名称;沃尔特"发现我们立即从wheres_walter函数返回全名,而无需继续迭代列表。