我正在处理一些代码,这些代码从某些传入数据创建特定格式的数据包,其中还包括一个时间戳(应该是生成数据的第一个数据位的时间)。在(简化)高级别,这看起来像:
template <typename T>
class packetizer
{
public:
set_payload(const T* data, uint16_t length, uint32_t timestamp);
};
还需要能够零散地添加数据;类似的东西:
uint16_t initial_data(const T* data, uint16_t length, uint32_t timestamp);
uint16_t append_data(const T* data, uint16_t length);
此处,时间戳应仅在initial_data
调用中添加一次。这一切都有效,并且可以在运行时进行检查,但到目前为止,我一直在努力提供尽可能编译时安全的API - 我希望在编译时强制执行上述不变量。我想到这样做的一种方法是返回一个代理:
struct proxy_packetizer
{
private:
packetizer<T>& packet_ref;
public:
uint16_t append_data(const T* data, uint16_t length)
{
// forward call to packet_ref
}
};
template <typename T>
class packetizer
{
public:
proxy_packetizer initial_data(const T* data, uint16_t length, uint32_t timestamp);
};
使用它看起来像:
packetizer p;
auto p2 = p.initial_data(data, length, timestamp);
p2.append_data(....);
auto pkt = p2.create_packet(...);
然而,这有点笨拙,而且仍然容易出错。如果我能以某种方式拥有看起来更像的API,我更喜欢:
packetizer p;
p.initial_data(data, length, timestamp);
p.append_data(...);
auto pkt = p.create_packet();
在编译时强制执行:
initial_data
被调用一次,每个数据包只调用一次。append_data
后才能调用initial_data
。create_packet
重置此内容(因此必须再次调用initial_data
)。是否有任何编译时方式来强制执行这些类型的状态转换?
答案 0 :(得分:1)
我同意@TonyD关于采用RAII方法的评论。我们的想法是将packetizer::packetizer(...)
转换为构造函数timestamp
。这就是template <typename T>
class packetizer
{
public:
packetizer(const T* data, uint16_t length, uint32_t timestamp);
uint16_t append_data(const T* data, uint16_t length);
};
只会设置一次的方式:
operator new
由于初始数据可能在运行时间的任何时间出现,因此您可以使用std::unique_ptr<packetizer<T>> packetizer = new Packetizer<T>(data, length, timestamp);
...
packetizer->append_data(data, length);
:
set_payload()
从问题中提到的任何内容来看,我都不能对//Array of videos
var MyVideos=["E6RGMRamAFk","IHQr0HCIN2w","CogIXrea6A4"];
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
//Player is ready, cue the array of videos into the playlist.
player.cuePlaylist(MyVideos);
}
function onPlayerStateChange(event) {
}
说些什么;但如果它容易出错,那么我们应该通过改变设计来更好地消除它。
答案 1 :(得分:0)
在Rust中运行IMAP State Machine的实现后,在编译时验证,看起来我正在寻找的是Substructural Type System的标题,在这种情况下,可能是仿射型系统。
我没有尝试过实现它,但可能只使用move-only类型。