简体   繁体   English

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

[英]Does a syntax for this exist? In any language?

It seems pretty common to me to have an argument, in a dynamically typed language that is either an Object or a key to lookup that object. 在我看来,以一种动态类型化的语言提供一个参数(这既是对象又是查找该对象的键)很普遍。 For instance when I'm working with a database I might have a method getMyRelatedStuff(person) 例如,当我使用数据库时,我可能有一个方法getMyRelatedStuff(person)

All I really need to lookup the related stuff is the id of the person so my method could look like this in python: 我真正需要查找的相关信息是该人的ID,因此我的方法在python中可能如下所示:

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

Or going the other direction: 或朝另一个方向:

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

EDIT: I am looking for a built in syntax for this, the closest I can think of is implicit and explicit keywords in C# that allow you to define a cast between types. 编辑:我正在为此寻找一个内置的语法,我能想到的最接近的是C#中的隐式和显式关键字,它们允许您定义类型之间的转换。

I study programming languages for a living. 我以编程语言为生。 I've never seen a language with a built-in syntax for that operation. 我从未见过针对该操作带有内置语法的语言。 I'm not even sure what you want such a syntax to look like, especially since you can define a function for any of these patterns. 我什至不确定您希望这种语法看起来像什么,尤其是因为您可以为任何这些模式定义一个函数。

People who like extensible syntax tend to define Lisp macros :-) 喜欢可扩展语法的人倾向于定义Lisp宏:-)

Are you looking for function overloading ? 您是否正在寻找函数重载 For example: 例如:

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

Any OO strongly-typed language should be able to do that. 任何面向对象的强类型语言都应该能够做到这一点。

For dynamically-typed languages though I'm not aware of any other way than manually doing some kind of type check (instanceof) operation, and that method can get nasty really fast. 对于动态类型的语言,我除了手动进行某种类型检查(instanceof)操作外,不知道其他任何方法,而且该方法可以很快地变得讨厌。 You're better off just doing what we did before OOP: use differently-named functions, for example: 您最好只做我们在OOP之前所做的事情:使用名称不同的函数,例如:

doSomethingByName(personName);
doSomethingById(personId);

If your code is well-structured otherwise, most of these "duplicate" functions will be pretty small. 如果您的代码结构合理,那么大多数这些“重复”功能将非常小。

方案,LISP或几乎任何带有宏的语言。

You can do this in any language that doesn't check the type of function parameters at compile time. 您可以使用在编译时不检查函数参数类型的任何语言来执行此操作。

JavaScript: 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;
}

I've never seen built-in syntax for this in any language I've used. 我从未用过我使用的任何语言看到过内置语法。

Note that in Python this is typically handled by exceptions: 请注意,在Python中,这通常由异常处理:

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

but preferably: 但最好:

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

and as for someFileStuff : 至于someFileStuff

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

Try to avoid using built-in names like id and file in your code; 尽量避免在代码中使用内置名称,例如idfile they introduce subtle bugs to your programs. 它们会在您的程序中引入细微的错误。

Lisp Lisp

This can easily be implemented using Lisp macros: 这可以使用Lisp宏轻松实现:

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

You can use that expression like this: 您可以这样使用该表达式:

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

That will expand to: 它将扩展为:

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

Macros are incredible. 宏太不可思议了。 I personally refuse to use any language that doesn't have them. 我个人拒绝使用任何没有它们的语言。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM