【踩坑指南2.0 2025最新】Scala中如何在命令行传入参数以运行主函数

这个地方基本没有任何文档记录,在学习的过程中屡屡碰壁,因此记录一下这部分的内容,懒得看可以直接跳到总结看结论。

踩坑步骤

首先来看看书上让我们怎么写:

//main.scala
object Start {def main(args:Array[String]) = {try {val score = args(1).toIntval s = Students2(args(0), score)println(s.toString)} catch {case ex: ArrayIndexOutOfBoundsException => println("Arguments are deficient!")case ex: NumberFormatException => println("Second argument must be a Int!")}}
}

之后,书上说我们执行下面的编译和运行指令即可运行:

scala students2.scala Start.scala
scala Start Tom

事实上,我们会获得以下报错:

jia@J-MateBookEGo:~/scala_test$ scala Start Tom
[error]  Start is not a scala sub-command and it is not a valid path to an input file or directory.
Try viewing the relevant help to see the list of available sub-commands and options.scala --help
Tom: input file not found
Try viewing the relevant help to see the list of available sub-commands and options.scala --help

经过检查,已经生成了一系列.class的JVM可执行文件,但似乎scala拒绝执行。

但是出于严谨,我们需要考虑是否是我们的代码编写有问题,因此我们来到scala的官网:

main 方法 | Scala 3 — Book | Scala Documentation

果然,官网在这里提示我们建议使用Scala3的全新语法,它将不需要创建一个object和输入参数列表,而是使用更简洁的语法来完成,这在我们之前的debug中已经体验过,当需要传入参数时,官网的程序示例是这样的:(当然,官网表示针对Scala2的写法仍然支持,就是前面传入参数列表的写法)

@main def happyBirthday(age: Int, name: String, others: String*) =val suffix = (age % 100) matchcase 11 | 12 | 13 => "th"case _ => (age % 10) matchcase 1 => "st"case 2 => "nd"case 3 => "rd"case _ => "th"val sb = StringBuilder(s"Happy $age$suffix birthday, $name")for other <- others do sb.append(" and ").append(other)sb.toString

然后官网说执行如下编译后运行指令可以得到结果:

$ scala happyBirthday 23 Lisa Peter
Happy 23rd Birthday, Lisa and Peter!

实际上,它又报错了,和之前是一样的:

jia@J-MateBookEGo:~/scala_test$ scala happyBirthday 23 Lisa Peter
[error]  happyBirthday is not a scala sub-command and it is not a valid path to an input file or directory.
Try viewing the relevant help to see the list of available sub-commands and options.scala --help
23: input file not found
Try viewing the relevant help to see the list of available sub-commands and options.scala --help
Lisa: input file not found
Try viewing the relevant help to see the list of available sub-commands and options.scala --help
Peter: input file not found
Try viewing the relevant help to see the list of available sub-commands and options.scala --help

根据之前debug的经验,这应该是由于编译器版本更新导致的。我们在之前的文章中使用新的执行指令解决了这个问题,它要求我们显式写出run:前情提要(没错,这个官网仍然是错的)

于是我们尝试使用这条指令运行:

jia@J-MateBookEGo:~/scala_test$ scala run -cp . -M happyBirthday
Illegal command line: more arguments expected

非常好,现在这个程序成功运行了,但如果想要传入参数,它又报错了 

jia@J-MateBookEGo:~/scala_test$ scala run -cp . -M happyBirthday 22
[error]  22: input file not found
Try viewing the relevant help to see the list of available sub-commands and options.scala run --help

那么我们现在百思不得其解,是否是这种写法不再被支持了?网上无法找到任何资料。万念俱灰之时,我们又找到了github这个提问Document starting programs compiled by scalac in the current working directory · Issue #3132 · VirtusLab/scala-cli · GitHub

根据回答的内容,我们顺藤摸瓜找到了Scala CLI的官网,没错,这次终于找到罪魁祸首了:

Migrating from the old Scala runner | Scala CLI 

在这里说明,

从SIP-46开始,Scala CLI已被接受为新的Scala命令。

在这种情况下,本指南的目的是强调旧的scala脚本和scala CLI之间的主要区别,以使用户尽可能顺利地进行迁移。

因此,我们之前的命令很多都不再被支持,这是导致错误的根本原因。但是Scala的官网并没有在这里更新使用Scala CLI的指令。

当我们从官网下载最新的Scala,Scala CLI已经作为原生指令被提供,也就是说我们现在使用的scala指令就是以前的scala-cli。

那么我们能不能仍然使用以前的编译器呢,答案是可以,但我们需要使用指令scala_lagacy,这里说明如下

是否可以使用旧的Scala runner?

是的,尽管它的用法已被弃用,但在scala_legacy命令下仍然可以使用它。然而,它很可能在未来的版本中被删除。

 那我们进行测试,看看最新版本是否仍然支持:

jia@J-MateBookEGo:~/scala_test$ scala_legacy -version
scala_legacy: command not found

效率真高啊,说删就删,这种完全牺牲针对旧版本的兼容性的操作令人费解。但也没办法,看来我们只能学习新的指令,看看他们有什么区别,此处我们直接引用一段官网的内容:

老方法

在旧的运行程序中,第一个参数被视为输入源,而第二个及之后的参数被视为程序参数。

@main def main(args: String*): Unit = println(args.mkString(" "))

scala_legacy Source.scala programArg1 programArg2

由于第一个参数之后的所有内容都必须作为程序参数任意读取,而不管格式如何,因此必须在源输入之前传递所有运行程序选项。可以使用下面的语句按照老方法执行:

scala_legacy -save Source.scala programArg1 programArg2

很好,这就是我们尝试使用的方案。显然,他们已经彻底删除了这个针对老方法的支持。 那么新方法是什么?

Scala CLI的使用方法

使用Scala CLI处理参数的默认方式,输入和程序参数必须加上--。两者的数量都没有限制。

def placeholder = println("Example extra source")
scala Source.scala Source2.scala -- programArg1 programArg2

此外,可以在输入部分之前传递一个Scala CLI子命令。例如,要调用上面的例子,显式地指定run子命令,像这样传递它:

scala run Source.scala Source2.scala -- programArg1 programArg2

 Runner选项可以传递到输入部分的任何位置(在--之前)。例如,以下所有示例都是将Scala版本显式指定为3.2的正确方法

scala -S 3.2 Source.scala Source2.scala -- programArg1 programArg2
scala Source.scala -S 3.2 Source2.scala -- programArg1 programArg2
scala Source.scala Source2.scala -S 3.2 -- programArg1 programArg2

 好的,我们试一下执行书上的代码,果然成功了。

jia@J-MateBookEGo:~/scala_test$ scala Start.scala students2.scala -- Tom
Arguments are deficient!
jia@J-MateBookEGo:~/scala_test$ scala Start.scala students2.scala -- Tom aaa
Second argument must be a Int!
jia@J-MateBookEGo:~/scala_test$ scala Start.scala students2.scala -- Tom 100
Tom's score is 100.

另外这个网页也展示了一些别的信息,主要是关于版本的变更导致一些语法不被支持。

比如以下这个代码:

println(args.mkString(" "))

它在3.x的版本中不再支持。

scala script.scala -- Hello world
[error] ./ScriptInScala.scala:1:1
[error] Illegal start of toplevel definition
[error] println(args.mkString(" "))
[error] ^^^^^^^
Error compiling project (Scala 3.2.2, JVM)
Compilation failed

像2.x版本中的object和参数列表法定义main函数仍然支持,但推荐使用@main方法。

总结

Start.scala中的代码:

//Start.scala
object Start {def main(args:Array[String]) = {try {val score = args(1).toIntval s = Students2(args(0), score)println(s.toString)} catch {case ex: ArrayIndexOutOfBoundsException => println("Arguments are deficient!")case ex: NumberFormatException => println("Second argument must be a Int!")}}
}

students2.scala中的代码:

class Students2(val name:String, var score: Int) {def apply(s:Int) = score = sdef display() = println("Current core is " + score + ".")override def toString = name + "'s score is '" + score + "."
}object Students2 {def apply(name: String, score: Int) = new Students2(name, score)
}

编译和执行命令:(别用scalac了,因为官网都没写scalac后如何执行)

jia@J-MateBookEGo:~/scala_test$ scala Start.scala students2.scala -- Tom
Arguments are deficient!
jia@J-MateBookEGo:~/scala_test$ scala Start.scala students2.scala -- Tom aaa
Second argument must be a Int!
jia@J-MateBookEGo:~/scala_test$ scala Start.scala students2.scala -- Tom 100
Tom's score is 100.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/502770.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据分析思维(七):分析方法——群组分析方法

数据分析并非只是简单的数据分析工具三板斧——Excel、SQL、Python&#xff0c;更重要的是数据分析思维。没有数据分析思维和业务知识&#xff0c;就算拿到一堆数据&#xff0c;也不知道如何下手。 推荐书本《数据分析思维——分析方法和业务知识》&#xff0c;本文内容就是提取…

CSS 之 position 定位属性详解

CSS系列文章目录 CSS 之 display 布局属性详解 CSS 之 position 定位属性详解一文搞懂flex布局 【弹性盒布局】 文章目录 CSS系列文章目录一、前言二、静态定位&#xff1a;position:static&#xff1b;二、相对定位&#xff1a;position:relative三、绝对定位&#xff1a;pos…

麒麟信安云在长沙某银行的应用入选“云建设与应用领航计划(2024)”,打造湖湘金融云化升级优质范本

12月26日&#xff0c;2024云计算产业和标准应用大会在北京成功召开。大会汇集政产学研用各方专家学者&#xff0c;共同探讨云计算产业发展方向和未来机遇&#xff0c;展示云计算标准化工作重要成果。 会上&#xff0c;云建设与应用领航计划&#xff08;2024&#xff09;建云用…

微信小程序Uniapp

使用命令行创建项目&#xff08;vuets&#xff09; npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project然后用HBX打开项目 再安装依赖 npm i 再运行开发版本&#xff0c;生成dist目录 pnpm dev:mp-weixin 注意要设置APPid 再用微信小程序打开

汇编环境搭建

学习视频 将MASM所在目录 指定为C盘

计算机网络--路由表的更新

一、方法 【计算机网络习题-RIP路由表更新-哔哩哔哩】 二、举个例子 例1 例2

热备份路由HSRP及配置案例

✍作者&#xff1a;柒烨带你飞 &#x1f4aa;格言&#xff1a;生活的情况越艰难&#xff0c;我越感到自己更坚强&#xff1b;我这个人走得很慢&#xff0c;但我从不后退。 &#x1f4dc;系列专栏&#xff1a;网路安全入门系列 目录 一&#xff0c;HSRP的相关概念二&#xff0c;…

今日头条ip属地根据什么显示?不准确怎么办

在今日头条这样的社交媒体平台上&#xff0c;用户的IP属地信息对于维护网络环境的健康与秩序至关重要。然而&#xff0c;不少用户发现自己的IP属地显示与实际位置不符&#xff0c;这引发了广泛的关注和讨论。本文将深入探讨今日头条IP属地的显示依据&#xff0c;并提供解决IP属…

倍思氮化镓充电器分享:Super GaN伸缩线快充35W

快节奏的时代,在旅游、办公等场景下,一款高效、便捷的充电器可以让我们的生活更便捷、高效。今天就给大家推荐一款倍思氮化镓充电器——Super GaN伸缩线快充35W。它具备多重亮点,可以满足我们在许多场景下的充电需求,成为我们的得力助手。 倍思氮化镓Super GaN伸缩线快充35W的亮…

云架构Web端的工业MES系统设计之区分工业过程

云架构Web端的工业MES系统设计之区分工业过程 在当今数字化浪潮席卷全球的背景下,制造业作为国家经济发展的重要支柱产业,正面临着前所未有的机遇与挑战。市场需求的快速变化、客户个性化定制要求的日益提高以及全球竞争的愈发激烈,都促使制造企业必须寻求更加高效、智能的生产…

嵌入式linux中socket控制与实现

一、概述 1、首先网络,一看到这个词,我们就会想到IP地址和端口号,那IP地址和端口各有什么作用呢? (1)IP地址如身份证一样,是标识的电脑的,一台电脑只有一个IP地址。 (2)端口提供了一种访问通道,服务器一般都是通过知名端口号来识别某个服务。例如,对于每个TCP/IP实…

VScode SSH 错误:Got bad result from install script 解決

之前vscode好好的&#xff0c;某天突然连接报错如下 尝试1. 服务器没有断开,ssh可以正常连接 2. 用管理员权限运行vscode&#xff0c;无效 3. 删除服务器上的~/.vscode-server 文件夹&#xff0c;无效 试过很多后&#xff0c;原来很可能是前一天anaconda卸载导致注册表项 步…

GPT分区 使用parted标准分区划分,以及相邻分区扩容

parted 是一个功能强大的命令行工具&#xff0c;用于创建和管理磁盘分区表和分区。它支持多种分区表类型&#xff0c;如 MBR&#xff08;msdos&#xff09;、GPT&#xff08;GUID Partition Table&#xff09;等&#xff0c;并且可以处理大容量磁盘。parted 提供了一个交互式界…

关系分类(RC)模型和关系抽取(RE)模型的区别

目标不同 关系分类模型&#xff1a;对给定的实体对在给定句子中预测其关系类型。两阶段&#xff08;RC&#xff09; 关系抽取模型&#xff1a;从句子中识别出所有潜在实体对&#xff0c;并为其预测关系类型。一阶段&#xff08;NERRE&#xff09; 训练/预测阶段输入输出数据不…

VSCode编辑+GCC for ARM交叉编译工具链+CMake构建+OpenOCD调试(基于STM32的标准库/HAL库)

一、CMake安装 进入CMake官网的下载地址Get the Software&#xff0c;根据系统安装对应的Binary distributions。 或者在CMake——国内镜像获取二进制镜像安装包。 或者访问GitHub的xPack项目xPack CMake v3.28.6-1&#xff0c;下载即可。 记得添加用户/系统的环境变量&#…

【数据结构】链表(2):双向链表和双向循环链表

双向链表&#xff08;Doubly Linked List&#xff09; 定义&#xff1a; 每个节点包含三个部分&#xff1a; 数据域。前驱指针域&#xff08;指向前一个节点&#xff09;。后继指针域&#xff08;指向下一个节点&#xff09;。 支持从任意节点向前或向后遍历。 #define dat…

RK3588+麒麟国产系统+FPGA+AI在电力和轨道交通视觉与采集系统的应用

工业视觉识别系统厂家提供的功能主要包括&#xff1a; 这些厂家通过先进的视觉识别技术&#xff0c;实现图像的采集、处理与分析。系统能够自动化地完成质量检测、物料分拣、设备监控等任务&#xff0c;显著提升生产效率和产品质量。同时&#xff0c;系统具备高度的灵活性和可扩…

3 抢红包系统

我们还是按照我们分析问题的方法论开展 一 场景分析 我们分析的是集体活动的抢红包&#xff0c;比如春晚&#xff0c;大型活动红包&#xff0c;需要在网页操作的抢红包 抢红包的问题也是多个人抢资源的问题&#xff0c;可以和秒杀进行比对。但是也有很多不同的地方。 用户打…

数据库中的并发控制

并发操作带来的数据不一致性 1、并发控制:为了保证事务的隔离性和一致性&#xff0c;数据库管理系统需要对并发操作进行正确调度 并发控制的主要技术有:封锁、时间戳、乐观控制法、多版本并发控制等 并发操作带来的数据不一致性: ① 丟失修改:两个事务 T1 和 T2 读入同一数据…

ArcGIS Server 10.2授权文件过期处理

新的一年&#xff0c;arcgis server授权过期了&#xff0c;服务发不不了。查看ecp授权文件&#xff0c;原来的授权日期就到2024.12.31日。好吧&#xff0c;这里直接给出处理方法。 ArcGIS 10.2安装时&#xff0c;有的破解文件中会有含一个这样的注册程序&#xff0c;没有的话&…