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

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

踩坑步骤

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

//main.scala
object Start {
  def main(args:Array[String]) = {
    try {
      val score = args(1).toInt
      val 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) match
    case 11 | 12 | 13 => "th"
    case _ => (age % 10) match
      case 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).toInt
      val 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 = s
  def 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.

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【路径跟踪】PIDMPC

路径跟踪&#xff08;Path Tracking&#xff09;是指在实际行驶过程中&#xff0c;根据预先规划好的路径进行控制&#xff0c;能够沿着设定的路径行驶。常见的路径跟踪算法包括基于模型的控制方法&#xff08;如PID控制器&#xff09;、模型预测控制&#xff08;Model Predicti…

python3GUI--智慧交通监控与管理系统 By:PyQt5

文章目录 一&#xff0e;前言二&#xff0e;预览三&#xff0e;软件组成&技术难点1.软件组成结构2.技术难点3.项目结构 四&#xff0e;总结 大小&#xff1a;35.5 M&#xff0c;软件安装包放在了这里! 一&#xff0e;前言 博主高产&#xff0c;本次给大家带来一款我自己使…

HP 电脑开机黑屏 | 故障判断 | BIOS 恢复 | BIOS 升级

注&#xff1a;本文为 “HP 电脑开机黑屏 | 故障判断 | BIOS 恢复 | BIOS 升级” 相关文章合辑。 引文图片 csdn 转储异常&#xff0c;重传。 篇 1&#xff1a;Smart-Baby 回复中给出故障现象判断参考 篇 2、篇3 &#xff1a;HP 官方 BIOS 恢复、升级教程 开机黑屏&#xff0c…

三甲医院等级评审八维数据分析应用(一)--组织、制度、管理可视化篇

一、引言 1.1 研究背景与意义 在当今医疗领域,三甲医院作为医疗服务的核心载体,肩负着保障民众健康、推动医学进步的重任。随着信息技术的飞速发展,数据已成为医院运营管理、医疗质量提升以及科学决策的关键要素。三甲医院等级评审作为衡量医院综合实力与服务水平的重要标…

数据表中列的完整性约束概述

文章目录 一、完整性约束概述二、设置表字段的主键约束三、设置表字段的外键约束四、设置表字段的非空约束五、设置表字段唯一约束六、设置表字段值自动增加七、设置表字段的默认值八、调整列的完整性约束 一、完整性约束概述 完整性约束条件是对字段进行限制&#xff0c;要求…

关于PINN进一步的探讨

pinn 是有监督、无监督、半监督&#xff1f; PINN&#xff08;Physics-Informed Neural Networks&#xff0c;物理信息神经网络&#xff09;通常被归类为一种有监督学习的方法。在PINN中&#xff0c;神经网络的训练过程不仅依赖于数据点&#xff08;例如实验观测数据&#xff0…

VUE条件树查询 自定义条件节点

之前实现过的简单的条件树功能如下图&#xff1a; 经过最新客户需求确认&#xff0c;上述条件树还需要再次改造&#xff0c;以满足正常需要&#xff01; 最新暴改后的功能如下红框所示&#xff1a; 页面功能 主页面逻辑代码&#xff1a; <template><div class"…

游戏如何检测iOS越狱

不同于安卓的开源生态&#xff0c;iOS一直秉承着安全性更高的闭源生态&#xff0c;系统中的硬件、软件和服务会经过严格审核和测试&#xff0c;来保障安全性与稳定性。 据FairGurd观察&#xff0c;虽然iOS系统具备一定的安全性&#xff0c;但并非没有漏洞&#xff0c;如市面上…

GraphRAG vs 传统 RAG:如何通过知识图谱提升 AI 检索能力

相比传统 RAG 仅能独立检索文本片段的局限性&#xff0c;GraphRAG通过构建实体关系图谱实现了信息间的连接&#xff0c;让 AI 能更完整地理解和检索复杂的关联信息&#xff0c;从而生成更准确和连贯的回答 问题背景: 想象有一本详细记录某人(X)成就的传记,每个章节都描述了他的…

Linux平台下实现的小程序-进度条

目录 1.换行、回车概念 2.缓冲区 2.1缓冲区 2.2强制刷新 3.进度条程序 Makefile文件 ProgressBar.h ProgressBar.c Main.c 执行结果 1.换行、回车概念 /n&#xff1a;换行回车&#xff08;\r&#xff1a;回车&#xff09; 2.缓冲区 如下图在vim编辑器中的命令模式下…

【顶刊TPAMI 2025】多头编码(MHE)之Part 6:极限分类无需预处理

目录 1 标签分解方法的消融研究2 标签分解对泛化的影响3 讨论4 结论 论文&#xff1a;Multi-Head Encoding for Extreme Label Classification 作者&#xff1a;Daojun Liang, Haixia Zhang, Dongfeng Yuan and Minggao Zhang 单位&#xff1a;山东大学 代码&#xff1a;https:…

【Leetcode】732. 我的日程安排表 III

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接&#x1f517; 当 k k k 个日程存在一些非空交集时&#xff08;即, k k k 个日程包含了一些相同时间&#xff09;&#xff0c;就会产生 k k k 次预订。 给你一些日程安排 [startTime, endTime…

Tableau数据可视化与仪表盘搭建-数据连接

连接数据有三种类型 第一种&#xff0c;连接到本地文件&#xff0c;例如Excel&#xff0c;csv&#xff0c;JSON等 第二种&#xff0c;连接到数据库&#xff0c;例如MySQL 注意&#xff1a;连接到数据库要安装对应的数据库的驱动的 连接本地文件

Chapter4.2:Normalizing activations with layer normalization

文章目录 4 Implementing a GPT model from Scratch To Generate Text4.2 Normalizing activations with layer normalization 4 Implementing a GPT model from Scratch To Generate Text 4.2 Normalizing activations with layer normalization 通过层归一化&#xff08;La…

搭建开源版Ceph分布式存储

系统&#xff1a;Rocky8.6 三台2H4G 三块10G的硬盘的虚拟机 node1 192.168.2.101 node2 192.168.2.102 node3 192.168.2.103 三台虚拟机环境准备 1、配置主机名和IP的映射关系 2、关闭selinux和firewalld防火墙 3、配置时间同步且所有节点chronyd服务开机自启 1、配置主机名和…

GPIO、RCC库函数

void GPIO_DeInit(GPIO_TypeDef* GPIOx); void GPIO_AFIODeInit(void); void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct); //输出 读 uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx,…

使用JMeter玩转tidb压测

作者&#xff1a; du拉松 原文来源&#xff1a; https://tidb.net/blog/3f1ada39 一、前言 tidb是mysql协议的&#xff0c;所以在使用过程中使用tidb的相关工具连接即可。因为jmeter是java开发的相关工具&#xff0c;直接使用mysql的jdbc驱动包即可。 二、linux下安装jmet…

Launcher3主页面加载显示流程分析

布局结构 抓取布局后&#xff0c;可以看到每个图标是一个DoubleShadowBubbleTextView&#xff0c;父布局是CellLayout、workspace。 我们可以在CellLayout添加子view打印出调用堆栈信息&#xff0c;可以整体上看页面加载显示流程。 主要类 Launcher.java&#xff1a;主界面&…

开发培训:慧集通(DataLinkX)iPaaS集成平台-基于接口的连接器开发(不需要认证机制)

一、开发一个简单的应用0源&#xff0c;本实例中对接的应用不需要接口认证 1、【连接管理-自建】新建应用源&#xff0c;保存并发布 代码示例 return {$$ - >//日志打印$$.$Log.info(日志打印) } 二、使用应用&#xff0c;建立应用连接 1、实例创建&#xff0c;【连接管理…

pikachu靶场--目录遍历和敏感信息泄露

pikachu靶场—目录遍历和敏感信息泄露 目录遍历 概述 在web功能设计中,很多时候我们会要将需要访问的文件定义成变量&#xff0c;从而让前端的功能便的更加灵活。 当用户发起一个前端的请求时&#xff0c;便会将请求的这个文件的值(比如文件名称)传递到后台&#xff0c;后台再…