Каковы некоторые другие языки, которые поддерживают “частичную специализацию”?

Попробуйте flatMap или concatMap

, используя оператор flatMap, вы можете сгладить подпоток в неблокирующей общедоступной

Flux<Object> test {

 method1().flatMap(obj -> {
        if (obj.getTotalItems() > 20) {
            return method2(obj)
                     .map(result -> {
                        obj.setItems(result);
                        return obj;
                     });
        }
        return Mono.just(obj);
  });
}

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

Одним из недостатков flatMap является то, что он не сохраняет порядок элементов, поэтому если у вас есть последовательность вышестоящих элементов, таких как [1, 2, 3, 4] с flatMap, есть вероятность, что порядок будет изменен из-за асинхронной природы подпотоков .

Чтобы сохранить порядок, вы можете использовать concatMap, который выравнивает только один поток за раз, поэтому есть гарантии, что порядок элементов выравнивания будет сохранен:

Flux<Object> test {

 method1().concatMap(obj -> {
        if (obj.getTotalItems() > 20) {
            return method2(obj)
                     .map(result -> {
                        obj.setItems(result);
                        return obj;
                     });
        }
        return Mono.just(obj);
  });
}

Примечание

[1115 ] Мутация объектов таким способом - не лучшая идея, и я бы предпочел использовать неизменный объект объект-образец в реактивном программировании

11
задан obecalp 24 December 2008 в 18:13
поделиться

6 ответов

Я боюсь, что C# не поддерживает частичную шаблонную специализацию.

Частичные шаблонные средства специализации:

У Вас есть базовый класс с двумя или больше шаблонами (дженерики / параметры типа). Параметры типа были бы <T, S>

В полученном (специализированном) классе Вы указываете на тип одного из параметров типа. Параметры типа могли быть похожими на это <T, интервал>.

Таким образом, то, когда кто-то использует (инстанцирует объекта), класс, где последний параметр типа является интервалом, производный класс используется.

1
ответ дан 3 December 2019 в 12:05
поделиться

D поддерживает частичную специализацию:

(сканирование для "частичного" в вышеупомянутых ссылках).

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

Вот определенный пример D swap. Это должно распечатать сообщение для подкачки, специализированной для Thing класс.

import std.stdio;    // for writefln

// Class with swap method

class Thing(T)
{
public:

    this(T thing)
    {
        this.thing = thing;
    }

    // Implementation is the same as generic swap, but it will be called instead.
    void swap(Thing that)
    {
       const T tmp = this.thing;
       this.thing = that.thing;
       that.thing = tmp;
    }

public:

    T thing;
}


// Swap generic function

void swap(T)(ref T lhs, ref T rhs)
{
    writefln("Generic swap.");

    const T tmp = lhs;
    lhs = rhs;
    rhs = tmp;
}

void swap(T : Thing!(U))(ref T lhs, ref T rhs)
{
    writefln("Specialized swap method for Things.");

    lhs.swap(rhs);
}

// Test case

int main()
{
    auto v1 = new Thing!(int)(10);
    auto v2 = new Thing!(int)(20);

    assert (v1.thing == 10);
    assert (v2.thing == 20);
    swap(v1, v2);
    assert (v1.thing == 20);
    assert (v2.thing == 10);

    return 0;
}
5
ответ дан 3 December 2019 в 12:05
поделиться

У Haskell есть перекрывающиеся экземпляры как расширение:

class Sizable a where
  size :: a -> Int

instance Collection c => Sizable c where
  size = length . toList

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

instance Sizable (Seq a) where
  size = Seq.length

См. также Усовершенствованное Перекрытие на HaskellWiki.

1
ответ дан 3 December 2019 в 12:05
поделиться

C#:

void Swap<T>(ref T a, ref T b) {   
  var c = a;   
  a = b;   
  b = c;
}

Я предполагаю, что (чистая) Haskell-версия была бы:

swap :: a -> b -> (b,a)
swap a b = (b, a)
-1
ответ дан 3 December 2019 в 12:05
поделиться

На самом деле Вы можете (не совсем; посмотрите ниже), делают это в C# с дополнительными методами:

public Count (this IEnumerable<T> seq) {
    int n = 0;
    foreach (T t in seq)
        n++;
    return n;
}

public Count (this T[] arr) {
    return arr.Length;
}

Затем вызов array.Count() будет использовать специализированную версию. "Не совсем" то, потому что разрешение зависит от статического типа array, не на типе выполнения. Т.е. это будет использовать более общую версию:

IEnumerable<int> array = SomethingThatReturnsAnArray();
return array.Count();
0
ответ дан 3 December 2019 в 12:05
поделиться

Java имеет дженерики, которые позволяют Вам делать подобные виды вещей.

-3
ответ дан 3 December 2019 в 12:05
поделиться