Существует ли синтаксис для этого? На каком языке? - PullRequest
0 голосов
/ 28 мая 2010

Мне кажется довольно распространенным аргумент на динамически типизированном языке, который является либо объектом, либо ключом для поиска этого объекта. Например, когда я работаю с базой данных, у меня может быть метод getMyRelatedStuff (person)

Все, что мне действительно нужно для поиска связанных вещей, это идентификатор человека, чтобы мой метод мог выглядеть следующим образом в 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 ]

9 голосов
/ 28 мая 2010

Я изучаю языки программирования для жизни.Я никогда не видел языка со встроенным синтаксисом для этой операции.Я даже не уверен, как вы хотите, чтобы такой синтаксис выглядел, тем более что вы можете определить функцию для любого из этих шаблонов.

Люди, которым нравится расширяемый синтаксис, склонны определять макросы Lisp: -)

3 голосов
/ 28 мая 2010

Вы ищете функцию перегрузки ? Например:

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

Любой ОО-язык со строгим контролем типов должен это делать.

Для языков с динамической типизацией, хотя я не знаю другого способа, кроме как вручную выполнить какую-либо операцию проверки типа (instanceof), и этот метод может стать очень неприятным Вам лучше просто делать то, что мы делали до ООП: использовать функции с разными именами, например:

doSomethingByName(personName);
doSomethingById(personId);

Если ваш код хорошо структурирован иначе, большинство из этих «дублирующих» функций будут довольно маленькими.

2 голосов
/ 28 мая 2010

Схема, LISP или любой другой язык с макросами.

1 голос
/ 29 мая 2010

Я никогда не видел встроенный синтаксис для этого на любом языке, который я использовал.

Обратите внимание, что в 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 в вашем коде; они вносят незначительные ошибки в ваши программы.

1 голос
/ 28 мая 2010

Вы можете сделать это на любом языке, который не проверяет тип параметров функции во время компиляции.

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;
}
0 голосов
/ 24 апреля 2011

Лисп

Это легко реализовать с помощью макросов 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))

Макросы невероятные. Я лично отказываюсь использовать любой язык, на котором их нет.

...