Заменить гигантский оператор переключения какой?

Они очень различаются по сигнатуре функции, которую они определяют.

  • Первый определяет сигнатуру обычной функции, которую можно настроить с помощью параметра типа при использовании, и этот тип становится фиксированным в сигнатуре
  • Второй определяет сигнатуру общей функции это функция, которая может принимать параметр любого типа T, причем T выводится (или указывается явно) при вызове функции.

Рассмотрим следующие объявления:

declare const fn: FnWithRequiredParam<number> 
declare const genericFn: FnWithParamInferred;

// T was fixed on declaration 
fn(1) // ok
fn("1") // err  

// T is decded by the caller
genericFn(1) // ok T is number for this call
genericFn("1") // ok T is string  for this call
genericFn<number>("1") // err T was specified as number but string was passed in 

Причиной ошибки, которую вы получаете, является то, что вы пытаетесь назначить функцию с параметром number для функции, которая должна принимать параметр любого типа T, с T, который должен определять вызывающий функции. Только универсальная функция может соответствовать типу FnWithParamInferred

var f: FnWithParamInferred = <T>(a: T) => { console.log(a) }

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

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

var f = (a: number) => { console.log(a) } // inferred as (a: number) => void

Или вы можете определить универсальную вспомогательную функцию для вывода T, но ограничить сигнатуру функции основан на FnWithRequiredParam

function createFunction<T>(fn: FnWithRequiredParam<T>) {
    return fn;
}

var f = createFunction((a: number) => { console.log(a) }) // inferred as FnWithRequiredParam<number>
17
задан Community 23 May 2017 в 10:33
поделиться

6 ответов

Используйте словарь, который отображает имена тега к обработчику тегов.

25
ответ дан 30 November 2019 в 11:32
поделиться

Вы хотите условное выражение замены с полиморфизмом . Примерно:

string getContent(const string& name) {
    myType obj = factory.getObjForName(name);
    obj.doStuff();
}

, где doStuff перегружается.

4
ответ дан 30 November 2019 в 11:32
поделиться

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

ОБНОВЛЕНИЕ: комментарий Steven поднимает важный вопрос - Вы захотите, чтобы Ваши шаблоны были допустимым XHTML, если Вы решите пойти путем XSLT. Также - я использовал бы другой разделитель для Ваших заменяющих маркеров. Что-то менее вероятно для появления естественно. Я использовал #! PLACEHOLDER#! в моем CMS.

3
ответ дан 30 November 2019 в 11:32
поделиться

я объединю 3 идеи:

  1. (от Steven Hugig): используйте метод фабрики, который получает Вас другой класс для каждого селектора.
    • (от Neil Butterworth): в фабрике используйте словарь, таким образом, Вы избавляетесь от большого switch(){}.
    • (мой): добавьте setup() метод к каждому классу обработчика, который добавляет себя (или новый экземпляр класса) к словарю.

объяснение немного:

  • делают абстрактный класс, который имеет static dict и методы для регистрации экземпляра в селекторной строке.
  • на каждом подклассе setup() метод регистрирует себя в dict
  • суперкласса, который метод фабрики немного больше, чем словарь читал
3
ответ дан 30 November 2019 в 11:32
поделиться

Вместо парсинга, попытались просто читать шаблон в строку и затем просто выполнить замены.

fileContents = fileContents.Replace("%title%", page->getTitle());
fileContents = fileContents.Replace("%color%", getBodyColor());
2
ответ дан 30 November 2019 в 11:32
поделиться

Как "Дядя" Bob Martin, упомянутый в предыдущем podacast с Joel и Jeff, в значительной степени, что-либо, что Вы придумываете, собирается по существу воспроизвести большой оператор переключения.

, Если Вы чувствуете себя лучше, реализовывая одно из решений, выбранных выше, это прекрасно. Это может сделать Ваш код более симпатичным, но под покрытиями, это чрезвычайно эквивалентно.

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

2
ответ дан 30 November 2019 в 11:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: