代码之家  ›  专栏  ›  技术社区  ›  powerj1984

基于字符串的调用函数

  •  6
  • powerj1984  · 技术社区  · 14 年前

    我正在将命令行参数传递给我的lisp程序,当它们击中我的主函数时,它们的格式如下:

    (1 1 1“”dot“”2 2“)
    < /代码> 
    
    

    我有一个点函数(它接受两个向量作为参数),并希望直接从参数调用它,但这是不可能的,因为类似(funcall(second args)…)的东西接收“dot”而不是dot作为函数名。

    我尝试了这种功能的变化: < BR> <代码> (defun remove quotes(s)
    (SETF(AREF S 0)') < /代码>

    在意识到引号实际上不是字符串的一部分之前,这是徒劳的。有没有一种简单的方法可以做到这一点,或者我应该检查每个字符串,然后调用适当的函数?

    ("1 1 1" "dot" "2 2 2") 
    

    我有一个点函数(它接受两个向量作为参数),并希望直接从参数调用它,但这是不可能的,因为像(funcall(second args)…)这样的东西接收“dot”而不是dot作为函数名。

    我尝试了这种功能的变化:
    (删除引号)
    (SETF(AREF S 0)')

    在意识到引号实际上不是字符串的一部分之前,这是徒劳的。有没有一种简单的方法可以做到这一点,或者我应该检查每个字符串,然后调用适当的函数?

    3 回复  |  直到 12 年前
        1
  •  8
  •   Rainer Joswig Michael Fox    14 年前

    “1 1 1”是一个由五个字符组成的字符串:1、空格、1、空格和1。双引号不是字符串的一部分。

    (“1 1 1”“dot”“2 2 2”)是三个字符串的列表。

    上面没有“字符。“用于分隔s表达式中的字符串。

    如果你有一个点函数,你需要告诉我们它需要什么样的输入数据。 它需要两个数字列表吗?然后您必须将字符串“1 1 1”转换为数字列表。

    (with-input-from-string (in "1 1 1")
      (loop for data = (read in nil in)
       until (eq data in)
       collect data)))
    

    要从字符串“dot”中获取函数dot,首先找到符号dot,然后获取其符号函数。

    (symbol-function (find-symbol (string-upcase "dot")))
    

    对于查找符号,如果有一个特殊的包,则可能还需要指定包。

    将列表转换为矢量,然后是下一个构建基块。

    因此,您需要将函数的参数转换为向量(可能首先将它们转换为列表,如我上面所示)。然后您需要找到这个函数(见上文)。如果您有函数和参数,那么您可以使用funcall或apply(任何更方便的方法)调用函数。

        2
  •  2
  •   sepp2k    14 年前

    这个问题有点不清楚,但据我所知,你想知道的是,当给出清单时 ("1 1 1" "dot" "2 2 2") 作为计算表达式的输入 (dot "1 1 1" "2 2 2") . 在这种情况下,您可以这样做:

    (defun apply-infix (arg1 f arg2)
      (apply (intern (string-upcase f)) (list arg1 arg2)))
    (defun apply-list-infix (lst)
      (apply 'apply-infix lst))
    
    (apply-list-infix '("1 1 1" "dot" "2 2 2"))
    
        3
  •  2
  •   Matthias Benkard    14 年前

    funcall 不接受字符串作为函数指示符。你需要给它一个符号。你可能想做的是:

    1. 将字符串转换为大写(lisp符号通常是大写的,即使它看起来像lisp不区分大小写,这仅仅是因为读卡器将默认情况下读取的所有符号都大写了)。( string-upcase )
    2. 创建或查找具有给定名称的符号( intern )注意,如果 *package* 不是根据函数名所在的包设置的,需要将包名作为第二个参数提供给 实习生 .

    例如(对于名为 dot 包内 cl-user :

    (funcall (intern (string-upcase "dot") 'cl-user) ...)