[英]How to ensure type check a function returns the same reference for same arguments
I have a bunch of functions that combines each other to return new objects.我有一堆相互结合以返回新对象的函数。 Some functions return sets composed of return values of these other functions.
一些函数返回由这些其他函数的返回值组成的集合。 I want to get the same object reference out of these functions for same arguments, so the set doesn't contain duplicates.
我想从这些函数中为相同的 arguments 获得相同的 object 参考,因此该集合不包含重复项。
type A = { a: number, b: number };
type A2 = { c: A, d: A };
function makeA(a: number, b: number): A {
return {
a, b
};
}
function makeA2(c: A, d: A): A2 {
return { c, d };
}
console.log(makeA(2, 3) === makeA(2, 3)); // I want this to be true
let res = [
makeA2(makeA(1,1), makeA(1,2)),
makeA2(makeA(1,1), makeA(1,2)),
makeA2(makeA(1,1), makeA(1,2)),
makeA2(makeA(1,1), makeA(1,2))
];
console.log(new Set(res)); // so I get a single element in this list
I've tried building a utility function called DB that keeps a map the two arguments that the functions take to the return value of the function, and on second call return from the cached value, but I am still getting duplicates, I think I am missing to wrap some functions, or there is a fundamental flaw in my logic. I've tried building a utility function called DB that keeps a map the two arguments that the functions take to the return value of the function, and on second call return from the cached value, but I am still getting duplicates, I think I am缺少包装一些功能,或者我的逻辑存在根本缺陷。
Yes, you would need to cache the return values of makeA
and makeA2
so that the same inputs result in the same outputs.是的,您需要缓存
makeA
和makeA2
的返回值,以便相同的输入产生相同的输出。 There are a number of ways to do this, but the important thing is to make sure that you are identifying "the same inputs" in robust way.有很多方法可以做到这一点,但重要的是确保您以稳健的方式识别“相同的输入”。
Here's one possible implementation, which maintains a separate cache for each function.这是一种可能的实现,它为每个 function 维护一个单独的缓存。 There's some code duplication here, so there's an opportunity to streamline it, but the point is to show something that works:
这里有一些代码重复,所以有机会简化它,但重点是展示一些有效的东西:
function makeA(a: number, b: number): A {
const key = a + ";" + b;
let ret = makeA.cache.get(key);
if (!ret) {
ret = { a, b };
makeA.cache.set(key, ret);
}
return ret;
}
makeA.cache = new Map<string, A>();
function makeA2(c: A, d: A): A2 {
const key = c.a + ";" + c.b + ";" + d.a + ";" + d.b;
let ret = makeA2.cache.get(key);
if (!ret) {
ret = { c, d };
makeA2.cache.set(key, ret);
}
return ret;
}
makeA2.cache = new Map<string, A2>();
For makeA
, the "same inputs" are determined by concatenating the string representation of the two numeric inputs with a semicolon between them to get a string
-valued lookup key.对于
makeA
,“相同的输入”是通过将两个数字输入的字符串表示形式与它们之间的分号连接起来来确定的,以获得string
值的查找键。 For makeB
, I'm doing this with the four individual numeric subproperties.对于
makeB
,我使用四个单独的数字子属性来执行此操作。 Technically, you should only need to use the "identities" of the c
and d
objects, but doing this is more tedious (you might end up maintaining a Map<A, Map<A, A2>>
instance which is ) and doesn't necessarily buy you much.从技术上讲,您应该只需要使用
c
和d
对象的“身份”,但是这样做会更加乏味(您最终可能会维护一个Map<A, Map<A, A2>>
实例)并且没有不一定给你买太多。 If someone calls makeA2({a: 1, b: 2}, {a: 1, b: 2})
with object literals, do you want the result to be different from if someone calls it like const a = {a:1, b:2}; makeA2(a, a)
如果有人用 object 文字调用
makeA2({a: 1, b: 2}, {a: 1, b: 2})
,您是否希望结果与有人像const a = {a:1, b:2}; makeA2(a, a)
const a = {a:1, b:2}; makeA2(a, a)
? const a = {a:1, b:2}; makeA2(a, a)
? Probably not, if your goal is not to proliferate instances.如果您的目标不是增加实例,可能不会。
In each case we look up the key in the cache;在每种情况下,我们都会在缓存中查找键; if it's there, great.
如果它在那里,那就太好了。 If not, we create the entry at that key and return that.
如果没有,我们在该键处创建条目并返回它。
Let's see if it works:让我们看看它是否有效:
console.log(makeA(2, 3) === makeA(2, 3)); // true
let res = [
makeA2(makeA(1, 1), makeA(1, 2)),
makeA2(makeA(1, 1), makeA(1, 2)),
makeA2(makeA(1, 1), makeA(1, 2)),
makeA2(makeA(1, 1), makeA(1, 2))
];
console.log(new Set(res).size); // 1
Looks good.看起来不错。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.