You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SML/NJ中如何基于导入者相对路径引入其他文件?

解决SML/NJ多文件依赖的路径问题

别担心,这个问题是SML入门时超常见的小坎,我来给你两个靠谱的解决办法,尤其是第一个,是SML/NJ官方推荐的标准做法,完全能避开你说的路径坑~

方法一:用Compilation Manager(CM)管理依赖(强烈推荐)

CM是SML/NJ专门用来处理多文件代码的工具,它会自动识别文件之间的相对位置,不管你从哪个目录运行脚本,都能准确找到依赖文件,根本不用纠结路径问题。

具体步骤:

  1. 整理你的代码文件
    先把f1.sml里要共享的函数封装成一个结构(相当于其他语言里的模块),这样能明确哪些函数可以被外部调用:

    (* f1.sml *)
    structure F1 =
    struct
      fun add x y = x + y
      fun multiply x y = x * y
      -- 把你要在f2里用的所有函数都放在这个结构里
    end
    

    然后在f2.sml里直接引用这个结构就行,完全不用写use命令:

    (* f2.sml *)
    -- 直接用F1结构里的函数
    val sum = F1.add 3 5
    fun double num = F1.multiply num 2
    
  2. 创建CM配置文件
    在f1.sml和f2.sml所在的目录下,新建一个名为myproject.cm的文件,内容如下:

    Group is
      $/basis.cm
      f1.sml
      f2.sml
    end
    
    • $/basis.cm是用来引用SML的标准库,必须加上;
    • 然后按依赖顺序列出你的文件(f1要放在f2前面,因为f2依赖f1)。
  3. 加载整个项目
    不管你在哪个目录打开SML/NJ,只要运行下面的命令加载CM配置文件就行(写配置文件的相对路径,如果是当前目录就直接写文件名):

    CM.make "path/to/myproject.cm";
    

    这样CM会自动编译所有依赖文件,你就能正常使用f1里的函数了,完全不用管路径问题~

方法二:临时调整use的路径(不推荐长期用)

如果暂时不想用CM,也可以用一个小技巧让use找到正确的f1路径,但这个方法比较hack,局限性大,适合临时测试:

(* f2.sml *)
-- 获取当前f2.sml文件的路径
val f2FilePath = case SMLofNJ.getArgs () of
                    [path] => path
                  | _ => raise Fail "无法获取f2.sml的路径"
-- 构造f1.sml的相对路径
val f1FilePath = OS.Path.joinDirFile {dir = OS.Path.dir f2FilePath, file = "f1.sml"}
-- 加载f1.sml
val _ = use f1FilePath;

-- 现在可以用f1里的函数了
val sum = add 3 5

注意这个方法需要你运行f2.sml的时候把它的路径作为参数传入,比如在终端里执行:

sml f2.sml

但如果是从其他脚本导入f2,这个方法可能还是会出问题,所以还是更推荐用CM。

为啥use会有路径问题?

其实use命令的路径是相对于SML/NJ进程的当前工作目录,而不是f2.sml所在的目录。所以当你从其他地方导入f2时,工作目录变了,自然就找不到f1了。而CM是根据文件之间的相对位置来解析依赖的,所以完全不会有这个问题~

内容的提问来源于stack exchange,提问作者leolovesai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:06:19