- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我试图更好地理解如何在 Go 中使用 protected 空间。我来自 java,这意味着我可以通过 protected 继承访问值,因为这里只有组合,我想确保我走在正确的道路上。
问题:我想在子实现中设置一个值,但不在通用接口(interface)上公开一个 setter 。
当确实没有层次结构时,为“子类”提供 setter 的最佳方法是什么?
这意味着我想要:
type Bottom interface {
GetYouSome()
// rote things
SetSpeed(int)
DeliveryMechanism() chan string
}
请注意,没有 SetDeliveryMechanism(chan string)
方法。
我想我会从一个实现死记硬背的基础开始,这意味着实际的实现将提供“GetYouSome”方法。我也希望它们存在于不同的包中。将有许多实现,我希望命名空间被沙盒化(即它们都可以使用常量 DefaultPort
)。
为了说明这个问题,我做了一个小项目。它的布局如下:
.
└── src
├── main.go
└── parent
├── child
│ └── child.go
└── parent.go
在 child.go
中,我们实际上创建了一些类型的 Bottom
,但在 parent.go
中,我们实际上定义了样板代码( setter / getter )。问题是我无法在任何地方实例化 channel !
理想的实现应该是这样的:
//------------- parent.go -------------
package parent
type Bottom interface {
GetYouSome()
// rote things
SetSpeed(int)
DeliveryMechanism() chan string
}
// Intended to implement the boring things
type GenericBottom struct {
speed int
deliveryChan chan string
}
func (bot *GenericBottom) SetSpeed(speed int) {
bot.speed = speed
}
func (bot GenericBottom) DeliveryMechanism() chan string {
return bot.deliveryChan
}
//------------- child.go -------------
package child
import "parent"
func New(speed int) parent.Bottom {
impl := new(Composite)
impl.name = "simple"
impl.SetSpeed(speed)
// illegal! not exported
// impl.deliveryChannel = make(chan string)
return impl
}
// intended so that we can seamlessly treat the Composite
// as a Bottom
type Composite struct {
parent.GenericBottom
name string
}
func (a Composite) GetYouSome() {
fmt.Println("Inside the actual implementation")
}
我认为有两种方法可以解决这个问题。
(1) 创建一个子类来包装 GenericBottom
类,传递所有方法。真令人难过,它仍然存在我无法直接访问 deliveryChannel
类的问题。我必须在父包中构建一个 new
构造函数,然后在子类中显式设置实例。
//------------- parent.go -------------
func NewGenericBottom() GenericBottom {
return GenericBottom{0, make(chan string)}
}
//------------- child.go -------------
func New(speed int) parent.Bottom {
impl := new(ExplicitComposite)
impl.name = "explicit"
// now I can set the channel? Nope
// impl.gb = parent.GenericBottom{speed, make(chan string)}
impl.gb = parent.NewGenericBottom()
impl.SetSpeed(speed)
return impl
}
// this has to pass through each method
type ExplicitComposite struct {
gb parent.GenericBottom
name string
}
func (e ExplicitComposite) GetYouSome() {
fmt.Println("Inside the explicit implementation")
}
func (e ExplicitComposite) DeliveryMechanism() chan string {
return e.gb.DeliveryMechanism()
}
func (e *ExplicitComposite) SetSpeed(speed int) {
e.gb.SetSpeed(speed)
}
或者! (2) 我可以在 GenericBottom 上添加一个 setter 方法。但是任何使用 GenericBottom 的人都可以转换为访问权限吗?我不会真的受到“保护”。
像这样:
//------------- parent.go -------------
func (bot *GenericBottom) SetChannel(c chan string) {
bot.deliveryChan = c
}
//------------- child.go -------------
type CheatersBottom struct {
parent.GenericBottom
name string
}
func (a CheatersBottom) GetYouSome() {
fmt.Println("Inside the cheaters bottom")
}
func NewCheatersBottom(speed int) parent.Bottom {
impl := new(CheatersBottom)
impl.SetChannel(make(chan string))
impl.SetSpeed(speed)
return impl
}
当确实没有层次结构时,为“子类”提供 setter 的最佳方法是什么?
最佳答案
您的主要问题是您是一名 Java 程序员。我的意思不是刻薄或中伤 Java 程序员;我的意思是,Java 中的通用思维方式与您在 Go 中的设计思维方式完全不同。也许不如尝试用 C 编写 Haskell 代码那么多,但它们仍然是完全不同的思维方式。
我已经写了很多草稿试图“修复”你的代码,但你设计它的方式与没有真正概念继承的语言根本不一致。如果你发现自己曾经在 Go 中使用过“base”或“parent”这些词,甚至在某种程度上使用过“generic”这个词,你可能会与类型系统大打出手。我认为这是大多数从 OO 语言转向 Go 的人必须经历的阶段。
我建议查看 Go 标准库并查看它们如何布置包。通常,您会发现以下内容: 一个包将定义一个或多个接口(interface),以及在这些接口(interface)上运行的函数。然而,接口(interface)的实际具体实现的数量要么不存在,要么非常少。然后,在另一个包中,他们提供实用程序的具体实现。最引人注目的是,与您的代码相比,永远不会有任何部分实现,除非实现一个接口(interface)自动部分实现另一个接口(interface)。
您的 GenericBottom
不一定是“错误”的,我当然自己制作了隐藏的伪抽象类,但在 Go 中,您想要的是将它们不导出为 genericBottom
,并且在与所有具体实现相同的包中。那或在internal package从 Go 1.4 开始。
您现在可能会说,“但是如果我需要在别处定义我的接口(interface)的其他具体实现怎么办?”好吧,您将复制代码。这可以被视为(并且可能是)Go 类型系统的弱点,但在不同的包中实现接口(interface)时重复一些代码绝对是惯用的和常见的。这就是像 internal
这样的东西是为了减轻一些。
另外请注意,不要将包视为类。一开始我也有这个问题。大中型的包里面有10个以上的文件是比较不起眼的。只要它们是一个单一的概念单元,那就是它们的用途。这就是通过让类型共享一个包来在 Go 中实现“ protected ”功能的方式(实际上更像是默认/无修饰符)。他们都可以访问彼此未导出的字段。
最后一条建议是不要从 NewX
方法返回接口(interface)。你应该(几乎)总是返回一个指向结构的指针。通常你想要构造一个类型,并将它作为接口(interface)传递给另一个方法,而不是首先接收接口(interface)。
我建议完全重写。挑战自己;每次你想到“ child 类”这样的词时,停下来做点别的事情。看看你能想出什么。我认为您会发现,虽然一开始有点困难,但通过以与类型系统协作的方式编写代码,您最终会完成更多工作,即使这会导致一些代码卡顿。
关于inheritance - 使用设置保护值的 Golang 继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32533992/
我知道这有点愚蠢,但我需要保护 javascript,从某种意义上说,我希望增加尽可能多的安全性,以免它被盗版。好吧,因为它是系统的核心组件。我打算用YUI compressor来压缩混淆。 但我还想
因此,当我的宏运行时,我有这些简单的子程序可以解除保护而不是保护东西,唯一的问题是我的一些工作表实际上是图表,并且在调用这些子程序时它们没有得到保护。如何更改我的代码以合并图表?谢谢! Sub Unp
有很多关于 preventing CSRF 的文章. 但我就是不明白:为什么我不能只解析目标页面表单中的 csrf token 并将其与我的伪造请求一起提交? 最佳答案 如果您能够将脚本代码注入(in
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 9年前关闭。 Improve this q
我正在使用一个包含用于docker创建的敏感信息的env文件。 但问题是它们并不安全。可以通过docker inspect轻松查看它们,因此,任何可以运行docker命令的用户都可以使用它们。 我正在
NSA在此处提供了保护.NET框架2.0版的指南:http://www.nsa.gov/ia/_files/app/I731-008R-2006.pdf 我想知道他们是否提供更高版本的指南,例如版本3
我编写了一个 Java 应用程序,并计划在线发布它。每个版本都将使用我制作的 secret 序列 key 锁定。 我需要从反编译器等保护我的 jar 文件。这是我到目前为止所做的: 用户在表格中输入他
我不知道为什么这不起作用。如果 ?Session=2 不是您发出的,那么您将返回您的帐户。 这是我的代码: query("SELECT * FROM user_host WHERE uid = '"
我是 elasticsearch 的新手,但我非常喜欢它。我唯一找不到也无法完成的是保护生产系统的 Elasticsearch 。我读了很多关于在 elasticsearch 前使用 nginx 作为
假设我有以下头文件: #ifndef TESTCLASS_H #define TESTCLASS_H #include class TestClass { public: TestClass
在 C++ 中,我有一个基类 A,一个子类 B。两者都有虚方法 Visit。我想在 B 中重新定义“访问”,但 B 需要访问每个 A(以及所有子类)的“访问”功能。 我有类似的东西,但它告诉我 B 无
我目前正在使用 Apache FOP 库生成 PDF。我希望这些 PDF 免受复制粘贴,因此人们必须使用实际的 OCR 库(或手动输入)来获取 PDF 上的信息。 FOP 显然提供了一些安全性,然后将
我有一个使用 JSONP 进行跨域 ajax 调用的脚本。这很好用,但我的问题是,有没有办法阻止其他站点访问这些 URL 并从中获取数据?我基本上想制作一个允许的站点列表,并且只返回列表中的数据。我正
我在基于 Html/Javascript 构建的 Web 应用程序上使用了一些全局变量。我跨页面(或部分页面)使用这些变量,有时它们用作 ajax 调用的发布数据。我的问题是:这有多安全?当然,我可以
我有一个扩展到多个类文件的大项目。这个项目是在赶时间前匆忙完成的。这对项目安全造成了影响。所以简单来说,理论上任何人都可以在我的项目中调用一个 AJAX 脚本并让它运行,因为脚本中的函数不是用户权限感
相当多的人对 ivé 发送给他们的 dll 真正感兴趣,他们不是那种应该经常免费赠送的类型... 我只是想知道,如果我要出售我的组件、用户控件等,我将如何在所有权/加密代码(如果可能)等方面保护它们。
我正在开发一个 PHP 库,我们将在其中为客户提供加密代码。该代码将包括一个他们可以实例化的主要类,该类将处理许可证验证并公开其使用方法。主类将实例化几个子类,每个子类都包含在自己的文件中。我怎样才能
我有一个以 VUEJS 作为前端的 Laravel 应用程序,我通过创建 API 路由获取数据。因此,例如获取帖子数据的路线将是 http://localhost/api/posts 保护路线的最佳方
在许多网页上,我们都包含外部脚本。无论是类似于 Facebook 的按钮、用于分析或广告系统的客户端代码、外部评论提供商还是其他东西。 那些脚本无法访问我的 Ajax 资源,因为一直在检查原始 hea
我目前正在使用 PHP/MySQL 开发一个公开和开放源代码的软件。我在一个文件夹中有几个重要的 SECRET TXT 文件。我在软件中使用它们,但问题是它们也可以被任何知道文件夹和文件名的人读取:
我是一名优秀的程序员,十分优秀!