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

是否存在这种情况的语法?用任何语言?

  •  0
  • Michael  · 技术社区  · 16 年前

    对于我来说,有一个动态类型语言的参数似乎很常见,它要么是一个对象,要么是查找该对象的键。例如,当我使用数据库时,我可能有一个方法getMyRelatedStuff(person)

    我真正需要的是查找相关内容的人的ID,所以我的方法在python中可以如下所示:

    def getMyRelatedStuff(person_or_id):
        id = person_or_id.id if isinstance(person,User) else person_or_id
        #do some lookup
    

    或者往另一个方向走:

    def someFileStuff(file_or_name):
        file = file_or_name if hasattr(file,'write') else open(file_or_name)
    

    编辑:我正在为这个寻找一个内置的语法,我能想到的最接近的是C中的隐式和显式关键字,它允许您定义类型之间的强制转换。

    6 回复  |  直到 15 年前
        1
  •  9
  •   Norman Ramsey    16 年前

    我以学习编程语言为生。我从来没有见过一种语言具有该操作的内置语法。我甚至不知道您希望这样的语法看起来是什么样子,特别是因为您可以为这些模式中的任何一个定义函数。

    喜欢可扩展语法的人倾向于定义lisp宏:-)

        2
  •  3
  •   Tore A.    16 年前

    你在找吗 function overloading ? 例如:

    doSomething(Person p);
    // these could do lookup and dispatch to doSomething(Person p)...
    doSomething(String personName);
    doSomething(Integer personId);
    

    任何OO强类型语言都应该能够做到这一点。

    对于动态类型语言,尽管除了手动执行某种类型检查(instanceof)操作之外,我不知道其他任何方法,但是这种方法可能会非常快变得令人讨厌。你最好做我们在OOP之前做的事情:使用不同的命名函数,例如:

    doSomethingByName(personName);
    doSomethingById(personId);
    

    如果您的代码结构良好,否则,这些“重复”函数中的大多数将非常小。

        3
  •  2
  •   leppie    16 年前

    Scheme、Lisp或几乎任何带有宏的语言。

        4
  •  1
  •   Amarghosh    16 年前

    您可以使用任何在编译时不检查函数参数类型的语言来执行此操作。

    JavaScript:

    function doSomething(person)
    {
      var name;
      if(typeof(person) == "string")
        name = person;
      else
        name = person.name;
      //you can simplify it to
      name = (typeof(person) == "string") ? name : person.name;
    }
    
        5
  •  1
  •   tzot    16 年前

    我从未见过 内置的 我用过的任何语言都有这样的语法。

    注意,在Python中,这通常由异常处理:

    def getMyRelatedStuff(person_or_id):
        "The verbose way"
        try:
            my_id= person_or_id.id
        except AttributeError:
            my_id= person_or_id
    

    但最好是:

    def getMyRelatedStuff(person_or_id):
        "The terse way"
        my_id= getattr(person_or_id, "id", person_or_id)
    

    至于 someFileStuff :

    def someFileStuff(file_or_name):
        try:
            fobj= open(file_or_name)
        except TypeError:
            fobj= file_or_name
    

    尽量避免使用诸如 id file 在您的代码中,它们会给您的程序引入细微的错误。

        6
  •  0
  •   jhuni    15 年前

    Lisp

    这可以使用lisp宏轻松实现:

    (defmacro get-if-not [func val alt]
      `(if (~func ~val)
        ~val
        ~alt))
    

    您可以使用如下表达式:

    (get-if-not file? file_or_name (open file_or_name))
    

    这将扩展到:

    (if (file? file_or_name) file_or_name (open file_or_name))
    

    宏是不可思议的。我个人拒绝使用任何没有它们的语言。