Julia中的函数抽象类型和多重分派

3

我希望根据对象类型让它们进行特定的交互。

举个例子,我的系统中有四个粒子,其中两个是类型 A,另外两个是类型 B。当类型 A 的粒子进行交互时,我想要使用这个函数:

function interaction(parm1, parm2)
    return parm1 + parm2
end

当B类型的对象进行交互时,我想使用这个函数。
function interaction(parm1, parm2)
        return parm1 * parm2
    end

当类型A与类型B交互时,我想使用函数。
function interaction(parm1, parm2)
        return parm1 - parm2
    end

这些函数故意设计得非常简单。
我想要计算一个基于两两交互的简单总和:
struct part
    parm::Float64
end

# part I need help with:
# initialize a list of length 4, where the entries are `struct part`, and the abstract types
# are `typeA` for the first two and `typeB` for the second two. The values for the parm can be
# -1.0,3, 4, 1.5 respectively

energy = 0.0
for i in range(length(particles)-1)
    for j = i+1:length(particles)
        energy += interaction(particles[i].parm, particles[j].parm)
    end
end

println(energy)

假设参数使用为particle[1].parm = -1particle[2].parm = 3particle[3].parm = 4particle[4].parm = 1.5,能量应考虑相互作用。
(1,2) = -1 + 3 = 2
(1,3) = -1 - 4 = -5
(1,4) = -1 - 1.5 = -2.5
(2,3) = 3 - 4 = -1
(2,4) = 3 - 1.5 = 1.5
(3,4) = 4 * 1.5 = 6

energy = 1

使用if语句做这件事几乎是琐碎的,但不可扩展。我想要一个干净、整洁的Julia方法...

2个回答

4
您可以这样做(在这种情况下,我使用最简单的实现形式,因为它足够明确,希望能理解):
struct A
    parm::Float64
end

struct B
    parm::Float64
end

interaction(p1::A, p2::A) = p1.parm + p2.parm
interaction(p1::B, p2::B) = p1.parm * p2.parm
interaction(p1::A, p2::B) = p1.parm - p2.parm
interaction(p1::B, p2::A) = p1.parm - p2.parm # I added this rule, but you can leave it out and get MethodError if such case happens

function total_energy(particles)
    energy = 0.0
    for i in 1:length(particles)-1
        for j = i+1:length(particles)
            energy += interaction(particles[i], particles[j])
        end
    end
    return energy
end

particles = Union{A, B}[A(-1), A(3), B(4), B(1.5)] # Union makes sure things are compiled to be fast

total_energy(particles)

-3

我不知道如何在你的编程语言中实现此功能,但是你需要的是面向对象编程中所谓的策略模式的类比。策略是一种可插拔、可重用的算法。在Java中我会创建一个如下的接口:

interface Interaction<A, B>
{
    double interact(A a, B b)
}

然后实现这个三次,并在需要相互交互的地方重复使用这些部分。另一种方法可以接受一个 Interaction 并在不知道它是如何实现的情况下使用它。我认为这就是你想要的效果。抱歉,我不知道如何翻译成你的方言。

这个答案基本上很糟糕,因为多重分派是Julia的一个特性,几乎使得Gang of 4的“设计模式”过时了。 - Oscar Smith
呃,多重分派并不是解决所有问题的灵丹妙药,有很多原因。 - Jonathan Locke
1
也许并非全部,但令人惊讶的是有很多:https://www.youtube.com/watch?v=kc9HwsxE1OY。至于其余部分,我想可以用高阶函数来解决 :) - phipsgabler
当然可以。你可以在图灵机中实现所有东西。在我看来,问题是“什么是适合这项工作的工具?” - Jonathan Locke
1
多重分派绝对是解决这种模式的良药。但是,展示在没有多重分派的语言中实现这一点有多尴尬当然是很有趣的。 - DNF

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接