技术杂记:Trait,2D 游戏,Monad 学习初步

这个月又差点整个博客空窗,以前写博客的勤勉到哪里去了!以后一定要一定要一定要每周写一点东西!!

于是我临时起意憋一点东西出来,那就这样啦。

2D 游戏开发

我在做的游戏,其实,严格来说还没有开始做……因为时间都花在造轮子上面了,首先我觉得只需要一些最基本的绘图功能就好了,于是用了功能很基础的 SDL,而不是游戏引擎,然后又觉得想要搞一些效果,所以尝试在 SDL 上面建立点点抽象,然后就一发不可收拾……现在我又嫌 SDL 在进行变幻的时候会出现锯齿,把目光投向功能更多更好开发更活跃的 SFML 上了。SFML 这个库的设计很不错,但是问题是这个库的 Rust 绑定有点糟糕,代码风格什么的就不说了,该有的抽象都没有做,很多对象都实现了诸如 set_rotate set_postition 这样的函数,但是没有抽离出来成为一个 Trait。现在我 folk 了,打算改进。

Trait

上面说到了 Trait,Trait 可以看作 Haskell 里面的 Type Class,Java 和 Go 里面的借口,只不过比接口要强大一点。

Trait 常常被译为特质,简单来说就是一个抽象的东西,要求你对特定的数据结构实现一些方法,如果满足了这个 Trait 你就可以把 Trait 应用到上面了。

具体可以看这里,我认为 Trait 是比继承更好的方式,尽管最初用 Trait 的时候可能会因为不能直接访问一个结构体里面的元素,也不能继承,会感觉很不方便,但是用久了会发现这一切是值得的。

(下文面向对象的语境是直觉的,传统的,大众的,不要给我说 Java C# 都不是面向对象语言,真正的面向对象是……)

继承是面向对象语言最基本的特性,但是继承也会带来许多的问题,比如说多重继承在所有语言里面都是问题重重,这不是设计问题,而是继承这种思想在面对这些情景的时候力不从心。而且出现了很多不必要的复杂度。而且加大了抽象的代价,这是万恶的,面向对象其实本质上就是一种简单的,傻瓜式的抽象准则,正因如此,其实抽象能力是被限制的。

时间所限,三月还有一个小时过去,我就不展开了,之后另开一篇文章。

Monad

Monad 这个东西非常神秘,让人心向往之,你想想“单子不就是自函子范畴上的幺半群”多么霸气!之前我看过各种科普,然后去看了点范畴论的 Wiki,感觉自己有点明白了自函子范畴上幺半群的意思,然后现在都忘了,昨天晚上看书《Haskell 函数式编程λ门》,里面举的例子就很好,让人一下子就懂了。

实际上 Monad 就是一个 Trait,对于实现了这个 Trait 的类型,类型里面可以“装”一些东西,又可以把一些东西装回去,比如说指针 Ptr<int> 就是一个 monad,你可以把一个数字装进去取出来再装回去……实际上 monad 就是那么简单的东西——箱子。

所以不用听别人讲什么什么本质上实际上就是个 Monad 就觉得难以企及,其实就是因为简单所以容易抽象,有些人经常会犯一个错误,A比B更抽象,所以A比B更本质,实际上真不一定是如此……不说了,再说就不是技术上的话题了。

言归正传,就我目前看到的内容,它常常用在“隔离”某些计算过程,这里我用 Python 来举例。假设有一些人比另一些人高贵,也就是贵族,这种人是不允许和平民通婚的,这时候我们就可以用 Monad 把两者隔离起来:

这里面贵族身份就是一个 monad。把一个家伙放到 Noble monad 里面就不会 JB 乱了。我们程序员又为封建社会的繁荣与稳定作出了杰出的贡献。

但是这里又出现了一个问题,就算是贵族也是个人吧?也要吃喝拉撒吧?关到 monad 里面不喂食也会死呀!再说不准贵族和平民之间结婚,但贵族和贵族总要结婚吧!!

当然可以把人从 monad 里面放出来,但是这就丧失了隔离的效果,花花公子又能 JB 乱了,这样不好不好。按照面向对象的方法就是继承 People,这样虽然很好理解但是实际上有很多问题,比如说丧失了一些抽象,依语言不同也可能无法简单的达成隔离的效果(运算符重载的类型签名并没有因为继承而改变),又比如说没有泛型的能力,以后出来一个外星贵族,程序员又要加班了。

Haskell 的方法很简单,能塞进去拖出来的就是 Monad 不是吗?那么用一些操作确保 Monad 可以拖出来做一些操作然后又塞回去,不会乱……

哎呦我肚子疼三月要过去了我要上厕所了,为了确保我的肚子不爆炸以及确保三月又一篇 Blog,详细下回分解。

技术杂记:Trait,2D 游戏,Monad 学习初步》上有4条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注