far编程语言 far语言 mud编程语言

far

介绍

far是一款可以运行在,Jvm,GraalVM上的编程语言,自带跨平台属性.

数据类型

far基本数据类型

  • int long string array float double byte bool map

对象类型

  • object

混合类型

  • var(模糊类型) 包括了基本类型和对象类型

数组

数组定义和赋值

string *data = ([1,2,3]);
数组和Js不一样 数组元素用([ ])包围
数组可以存储不同的数据类型

data=([1,2,"字符串"]);

字典 map

字典和JS不一样用的是({}) 包围元素
map data = ({"name":"far"});

表达式

解构表达式

(a,b) = test();
(a,b) = array;
(a,b) = ([1,2]);

三元表达式

var a = x==1 ? 100 : 99;

when 表达式

代替switch 的表达式,比switch 更强大,更方便!
when表达式具有返回值,每个分支的最后一个表达式作为返回值

->左边的表达式 只接受bool表达式的情况,比如

void main(){
    var testWhen = when(a=19){
        a==2 => {println("下面的分支不会执行....")};
        a in (1,2,3)=>{"是得,包含了2";};
        a in 1..20 =>println("是得1..20包含了他");
        !a =>println(a);
        _=>"默认分支,这个分支就算不写,编译器也会自动生成,所以when表达式一般默认返回0";
    };
    println(testWhen);
}
  • 如果test的返回值不是bool类型,就不是有效的bool表达式
  • 必须写默认分支_=>
  • when() 括号中的只能是赋值表达式,far的编译器需要做变量捕获

未来版本

  • when 也可以用来取代 if-else if链,从而达到简化的效果, 如果不提供参数,所有的分支条件都是简单的布尔表达式,而当一个分支的条件为真时则执行该分支:
when {
x.isOdd() => print("x is odd")
x.isEven() => print("x is even")
_=> print("x is funny")
}

语句

import语句

主要作用是将in后面的字符串存入Name,方便在当前文件全局使用

  • 如果括号表达式中的标识符,大于1个时,将以in后面的文件中的export语句导出为准,export只能导出方法
import (Name) in "xxx/xxxx";

return 语句

return 语句后面只能跟表达式或留空

for 语句

基本结构

for(初始器;循环条件表达式;计数器) {代码块}

  • 初始器和计数器支持逗号表达式
for(int a=0,q=1;a<100;i++,c++) {u+user();}
for(;a<1;){}
for(int a=0,q=1;a<100;i++,c++) {u+user();}
for(int x=1;a<1;){}
for(int x=1;;){}
for(int a=0,q=1;a<100;i++){
    for(;a<1;){}
    for(int a=0,q=1;a<100;i++,c++) {u+user();}
    for(int x=1;a<1;){}
    for(int x=1;;){}
}

如果for语句的代码块部分,没有代码,花括号也必须要添加
far没有while循环,所以for用语句代替while语句

for(;bool表达式;){

}

foreach 语句

语法

foreach(ident in ident|expr){ stmt|expr }

foreach进行数组和字典(map)的遍历

    string *s = (["2","3","4"]);
    map dats = ({
        "我是key":"我是val",
        "我是key1":"我是val111"
    });

    foreach( k, v in dats ){
        dats[k]="999";
        println(k+"---"+v);
    }


   foreach( v in s ){
        println(v);
   }


注意,不管是for还是foreach ,far不支持在循环中添加和删除数组、字典的元素,因为这是不好的编程习惯,容易造成BUG。

if else

if(a==1){
   aa=2;
}else aa=3;

if(a==1)aa=2;
else aa=3;

if(x==1) o=2;

类的继承 inherit

inherit "feature/treemap.c"

函数

函数定义

函数定义不需要专用的关键字,按以下形式即可

返回类型 函数名(参数类型 参数名){

}

int test(string s){
  return 1;
}

匿名函数

far的匿名函数可以捕获外部变量,如果匿名函数要修改外部的变量,只能是对象类型,基本类型无法修改.

var func = (x,y)-> println(x);

匿名方法在编译器处理阶段,会识别创建他时上下文中的变量。假设方法A创建了匿名方法B

void A(){
    int data =1;
    var B = ()->{
        println(data);
    }
}

如果匿名方法B创建了匿名方法C,C方法内部是无法使用data变量的

void A(){
    int data =1;
    var B = ()->{
       var C=()->{
            println(data);
       }
    }
}

除非在B方法中使用一次data

void A(){
    int data =1;
    var B = ()->{
       int data1=data;
       var C=()->{
            println(data1);
       }
    }
}

匿名函数分为创建阶段和调用阶段

如何在创建时就实现调用并传入多个参数?


var a = ([2,5,3]);
var b = 5;


var idx =  findNumber(a,([b]),(x,v)->{
    if(x<v[0]) return true;
    return false;
});

int findNumber(var o,var v,var f){
    for(int i;i<o.size();i++){
        if( f(o[i]),v ){
            return i;
        }
    }
    return -1;
}


上面代码展示了如何使用findNumber函数查找数组中值小于5的数的索引。

findNumber的第一个参数是原数组,b作为被查找的数,放在数组里传入匿名函数。

异常处理


void test1(){
    throw("test1方法抛出的异常");
}

void test(){
    test1();
}
void main()
{


    try {

        println("触发异常");
        test();
        test_throw();

        throw ("far");
        println("此处不会执行的!");
        return 1;//这个return 无效了...
    } catch (e) {//可选执行
        println(e.getMessage());
        for (int i;i < e.stackElements().size();i++)
        {
            println(e.stackElements().get(i).file() + ":" + e.stackElements().get(i).methodName() + ":" + e.stackElements().get(i).line());
        }

        println("catch代码执行了");
        
        try {
            println("try嵌套代码执行了");
        } catch (e1) {
            println("catch嵌套代码执行了");
        } finally {
            println("finally嵌套代码执行了");
        }
    } finally {

        println("外层finally执行了1");
        throw ("这个异常会是什么??");
        println("外层finally执行了2");
    }
    println("主体代码.....");
}

每个后缀为c的文件都是far的类文件,文件名就是类名,所以far无需使用class之类的关键字声明一个类.
每个函数/方法之外的变量声明都是这个类的字段,而不叫变量

类实例的创建

var obj = new("类文件");

静态方法和静态字段

静态字段

static string name;

调用时使用文件名::name
比如当前文件名是A
调用 A::name

静态方法

static void test(){

}

调用方式和调用静态字段一样

多线程

far可以轻松创建千万级线程,不输go语言的协程
thread

调用动态库(计划功能)

在far中可以轻松调用C/C++/GO/C# 创建的动态度,轻松读写进程的内存

取方法地址

&符号可以获取方法的地址

void test(){
    println("far语言");
}
void main(){
    var func = &test;
    func();
}

上面代码执行后输出`far语言``

posted @   方东信  阅读(127)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
历史上的今天:
2023-12-05 老年代一直增大,系统巨慢,内存泄漏
2023-12-05 Jpa mybatis mybatis plus 整合 混合使用时,jsqlparser一直报错
2017-12-05 springmvc请求参数获取的几种方法
2016-12-05 HttpServletRequest 报错 myeclipese支持tomcat
点击右上角即可分享
微信分享提示